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

Module db.
  Module states.
    Module state.
      Axiom DBBox :
        forall (E : Ty.t),
        (Ty.apply (Ty.path "revm::db::states::state::DBBox") [] [ E ]) =
          (Ty.apply
            (Ty.path "alloc::boxed::Box")
            []
            [
              Ty.dyn
                [
                  ("revm_primitives::db::Database::Trait", []);
                  ("core::marker::Send::AutoTrait", [])
                ];
              Ty.path "alloc::alloc::Global"
            ]).
      
      Axiom StateDBBox :
        forall (E : Ty.t),
        (Ty.apply (Ty.path "revm::db::states::state::StateDBBox") [] [ E ]) =
          (Ty.apply
            (Ty.path "revm::db::states::state::State")
            []
            [
              Ty.apply
                (Ty.path "alloc::boxed::Box")
                []
                [
                  Ty.dyn
                    [
                      ("revm_primitives::db::Database::Trait", []);
                      ("core::marker::Send::AutoTrait", [])
                    ];
                  Ty.path "alloc::alloc::Global"
                ]
            ]).
      
      (* StructRecord
        {
          name := "State";
          const_params := [];
          ty_params := [ "DB" ];
          fields :=
            [
              ("cache", Ty.path "revm::db::states::cache::CacheState");
              ("database", DB);
              ("transition_state",
                Ty.apply
                  (Ty.path "core::option::Option")
                  []
                  [ Ty.path "revm::db::states::transition_state::TransitionState" ]);
              ("bundle_state", Ty.path "revm::db::states::bundle_state::BundleState");
              ("use_preloaded_bundle", Ty.path "bool");
              ("block_hashes",
                Ty.apply
                  (Ty.path "alloc::collections::btree::map::BTreeMap")
                  []
                  [
                    Ty.path "u64";
                    Ty.apply
                      (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                      [ Value.Integer IntegerKind.Usize 32 ]
                      [];
                    Ty.path "alloc::alloc::Global"
                  ])
            ];
        } *)
      
      Module Impl_core_fmt_Debug_where_core_fmt_Debug_DB_for_revm_db_states_state_State_DB.
        Definition Self (DB : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "revm::db::states::state::State") [] [ DB ].
        
        (* Debug *)
        Definition fmt (DB : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; f ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let f := M.alloc (| f |) in
              M.read (|
                let~ names :=
                  M.alloc (|
                    M.alloc (|
                      Value.Array
                        [
                          M.read (| Value.String "cache" |);
                          M.read (| Value.String "database" |);
                          M.read (| Value.String "transition_state" |);
                          M.read (| Value.String "bundle_state" |);
                          M.read (| Value.String "use_preloaded_bundle" |);
                          M.read (| Value.String "block_hashes" |)
                        ]
                    |)
                  |) in
                let~ values :=
                  M.alloc (|
                    M.alloc (|
                      Value.Array
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "revm::db::states::state::State",
                            "cache"
                          |);
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "revm::db::states::state::State",
                            "database"
                          |);
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "revm::db::states::state::State",
                            "transition_state"
                          |);
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "revm::db::states::state::State",
                            "bundle_state"
                          |);
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "revm::db::states::state::State",
                            "use_preloaded_bundle"
                          |);
                          M.alloc (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "revm::db::states::state::State",
                              "block_hashes"
                            |)
                          |)
                        ]
                    |)
                  |) in
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "core::fmt::Formatter",
                      "debug_struct_fields_finish",
                      []
                    |),
                    [
                      M.read (| f |);
                      M.read (| Value.String "State" |);
                      M.read (| names |);
                      M.read (| values |)
                    ]
                  |)
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (DB : Ty.t),
          M.IsTraitInstance
            "core::fmt::Debug"
            (Self DB)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("fmt", InstanceField.Method (fmt DB)) ].
      End Impl_core_fmt_Debug_where_core_fmt_Debug_DB_for_revm_db_states_state_State_DB.
      
      Module Impl_revm_db_states_state_State_revm_db_emptydb_EmptyDBTyped_core_convert_Infallible.
        Definition Self : Ty.t :=
          Ty.apply
            (Ty.path "revm::db::states::state::State")
            []
            [
              Ty.apply
                (Ty.path "revm::db::emptydb::EmptyDBTyped")
                []
                [ Ty.path "core::convert::Infallible" ]
            ].
        
        (*
            pub fn builder() -> StateBuilder<EmptyDB> {
                StateBuilder::default()
            }
        *)
        Definition builder (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          match ε, τ, α with
          | [], [], [] =>
            ltac:(M.monadic
              (M.call_closure (|
                M.get_trait_method (|
                  "core::default::Default",
                  Ty.apply
                    (Ty.path "revm::db::states::state_builder::StateBuilder")
                    []
                    [
                      Ty.apply
                        (Ty.path "revm::db::emptydb::EmptyDBTyped")
                        []
                        [ Ty.path "core::convert::Infallible" ]
                    ],
                  [],
                  "default",
                  []
                |),
                []
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_builder : M.IsAssociatedFunction Self "builder" builder.
      End Impl_revm_db_states_state_State_revm_db_emptydb_EmptyDBTyped_core_convert_Infallible.
      
      Module Impl_revm_db_states_state_State_DB.
        Definition Self (DB : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "revm::db::states::state::State") [] [ DB ].
        
        (*
            pub fn bundle_size_hint(&self) -> usize {
                self.bundle_state.size_hint()
            }
        *)
        Definition bundle_size_hint
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "revm::db::states::bundle_state::BundleState",
                  "size_hint",
                  []
                |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "revm::db::states::state::State",
                    "bundle_state"
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_bundle_size_hint :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "bundle_size_hint" (bundle_size_hint DB).
        
        (*
            pub fn increment_balances(
                &mut self,
                balances: impl IntoIterator<Item = (Address, u128)>,
            ) -> Result<(), DB::Error> {
                // make transition and update cache state
                let mut transitions = Vec::new();
                for (address, balance) in balances {
                    if balance == 0 {
                        continue;
                    }
                    let original_account = self.load_cache_account(address)?;
                    transitions.push((
                        address,
                        original_account
                            .increment_balance(balance)
                            .expect("Balance is not zero"),
                    ))
                }
                // append transition
                if let Some(s) = self.transition_state.as_mut() {
                    s.add_transitions(transitions)
                }
                Ok(())
            }
        *)
        Definition increment_balances
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [ impl_IntoIterator_Item____Address__u128__ ], [ self; balances ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let balances := M.alloc (| balances |) in
              M.catch_return (|
                ltac:(M.monadic
                  (M.read (|
                    let~ transitions :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply
                              (Ty.path "alloc::vec::Vec")
                              []
                              [
                                Ty.tuple
                                  [
                                    Ty.path "alloy_primitives::bits::address::Address";
                                    Ty.path
                                      "revm::db::states::transition_account::TransitionAccount"
                                  ];
                                Ty.path "alloc::alloc::Global"
                              ],
                            "new",
                            []
                          |),
                          []
                        |)
                      |) in
                    let~ _ :=
                      M.use
                        (M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::collect::IntoIterator",
                                impl_IntoIterator_Item____Address__u128__,
                                [],
                                "into_iter",
                                []
                              |),
                              [ M.read (| balances |) ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let iter := M.copy (| γ |) in
                                M.loop (|
                                  ltac:(M.monadic
                                    (let~ _ :=
                                      M.match_operator (|
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::iter::traits::iterator::Iterator",
                                              Ty.associated,
                                              [],
                                              "next",
                                              []
                                            |),
                                            [ iter ]
                                          |)
                                        |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let _ :=
                                                M.is_struct_tuple (|
                                                  γ,
                                                  "core::option::Option::None"
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (| M.read (| M.break (||) |) |)
                                              |)));
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ0_0 :=
                                                M.SubPointer.get_struct_tuple_field (|
                                                  γ,
                                                  "core::option::Option::Some",
                                                  0
                                                |) in
                                              let γ1_0 :=
                                                M.SubPointer.get_tuple_field (| γ0_0, 0 |) in
                                              let γ1_1 :=
                                                M.SubPointer.get_tuple_field (| γ0_0, 1 |) in
                                              let address := M.copy (| γ1_0 |) in
                                              let balance := M.copy (| γ1_1 |) in
                                              let~ _ :=
                                                M.match_operator (|
                                                  M.alloc (| Value.Tuple [] |),
                                                  [
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (let γ :=
                                                          M.use
                                                            (M.alloc (|
                                                              BinOp.eq (|
                                                                M.read (| balance |),
                                                                Value.Integer IntegerKind.U128 0
                                                              |)
                                                            |)) in
                                                        let _ :=
                                                          M.is_constant_or_break_match (|
                                                            M.read (| γ |),
                                                            Value.Bool true
                                                          |) in
                                                        M.alloc (|
                                                          M.never_to_any (|
                                                            M.read (| M.continue (||) |)
                                                          |)
                                                        |)));
                                                    fun γ =>
                                                      ltac:(M.monadic
                                                        (M.alloc (| Value.Tuple [] |)))
                                                  ]
                                                |) in
                                              let~ original_account :=
                                                M.copy (|
                                                  M.match_operator (|
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_trait_method (|
                                                          "core::ops::try_trait::Try",
                                                          Ty.apply
                                                            (Ty.path "core::result::Result")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path "&mut")
                                                                []
                                                                [
                                                                  Ty.path
                                                                    "revm::db::states::cache_account::CacheAccount"
                                                                ];
                                                              Ty.associated
                                                            ],
                                                          [],
                                                          "branch",
                                                          []
                                                        |),
                                                        [
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path
                                                                  "revm::db::states::state::State")
                                                                []
                                                                [ DB ],
                                                              "load_cache_account",
                                                              []
                                                            |),
                                                            [
                                                              M.read (| self |);
                                                              M.read (| address |)
                                                            ]
                                                          |)
                                                        ]
                                                      |)
                                                    |),
                                                    [
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (let γ0_0 :=
                                                            M.SubPointer.get_struct_tuple_field (|
                                                              γ,
                                                              "core::ops::control_flow::ControlFlow::Break",
                                                              0
                                                            |) in
                                                          let residual := M.copy (| γ0_0 |) in
                                                          M.alloc (|
                                                            M.never_to_any (|
                                                              M.read (|
                                                                M.return_ (|
                                                                  M.call_closure (|
                                                                    M.get_trait_method (|
                                                                      "core::ops::try_trait::FromResidual",
                                                                      Ty.apply
                                                                        (Ty.path
                                                                          "core::result::Result")
                                                                        []
                                                                        [ Ty.tuple []; Ty.associated
                                                                        ],
                                                                      [
                                                                        Ty.apply
                                                                          (Ty.path
                                                                            "core::result::Result")
                                                                          []
                                                                          [
                                                                            Ty.path
                                                                              "core::convert::Infallible";
                                                                            Ty.associated
                                                                          ]
                                                                      ],
                                                                      "from_residual",
                                                                      []
                                                                    |),
                                                                    [ M.read (| residual |) ]
                                                                  |)
                                                                |)
                                                              |)
                                                            |)
                                                          |)));
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (let γ0_0 :=
                                                            M.SubPointer.get_struct_tuple_field (|
                                                              γ,
                                                              "core::ops::control_flow::ControlFlow::Continue",
                                                              0
                                                            |) in
                                                          let val := M.copy (| γ0_0 |) in
                                                          val))
                                                    ]
                                                  |)
                                                |) in
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path "alloc::vec::Vec")
                                                      []
                                                      [
                                                        Ty.tuple
                                                          [
                                                            Ty.path
                                                              "alloy_primitives::bits::address::Address";
                                                            Ty.path
                                                              "revm::db::states::transition_account::TransitionAccount"
                                                          ];
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "push",
                                                    []
                                                  |),
                                                  [
                                                    transitions;
                                                    Value.Tuple
                                                      [
                                                        M.read (| address |);
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.apply
                                                              (Ty.path "core::option::Option")
                                                              []
                                                              [
                                                                Ty.path
                                                                  "revm::db::states::transition_account::TransitionAccount"
                                                              ],
                                                            "expect",
                                                            []
                                                          |),
                                                          [
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.path
                                                                  "revm::db::states::cache_account::CacheAccount",
                                                                "increment_balance",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| original_account |);
                                                                M.read (| balance |)
                                                              ]
                                                            |);
                                                            M.read (|
                                                              Value.String "Balance is not zero"
                                                            |)
                                                          ]
                                                        |)
                                                      ]
                                                  ]
                                                |)
                                              |)))
                                        ]
                                      |) in
                                    M.alloc (| Value.Tuple [] |)))
                                |)))
                          ]
                        |)) in
                    let~ _ :=
                      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 "core::option::Option")
                                        []
                                        [
                                          Ty.path
                                            "revm::db::states::transition_state::TransitionState"
                                        ],
                                      "as_mut",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "revm::db::states::state::State",
                                        "transition_state"
                                      |)
                                    ]
                                  |)
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let s := M.copy (| γ0_0 |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "revm::db::states::transition_state::TransitionState",
                                    "add_transitions",
                                    []
                                  |),
                                  [ M.read (| s |); M.read (| transitions |) ]
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    M.alloc (| Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ] |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_increment_balances :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "increment_balances" (increment_balances DB).
        
        (*
            pub fn drain_balances(
                &mut self,
                addresses: impl IntoIterator<Item = Address>,
            ) -> Result<Vec<u128>, DB::Error> {
                // make transition and update cache state
                let mut transitions = Vec::new();
                let mut balances = Vec::new();
                for address in addresses {
                    let original_account = self.load_cache_account(address)?;
                    let (balance, transition) = original_account.drain_balance();
                    balances.push(balance);
                    transitions.push((address, transition))
                }
                // append transition
                if let Some(s) = self.transition_state.as_mut() {
                    s.add_transitions(transitions)
                }
                Ok(balances)
            }
        *)
        Definition drain_balances
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [ impl_IntoIterator_Item___Address_ ], [ self; addresses ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let addresses := M.alloc (| addresses |) in
              M.catch_return (|
                ltac:(M.monadic
                  (M.read (|
                    let~ transitions :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply
                              (Ty.path "alloc::vec::Vec")
                              []
                              [
                                Ty.tuple
                                  [
                                    Ty.path "alloy_primitives::bits::address::Address";
                                    Ty.path
                                      "revm::db::states::transition_account::TransitionAccount"
                                  ];
                                Ty.path "alloc::alloc::Global"
                              ],
                            "new",
                            []
                          |),
                          []
                        |)
                      |) in
                    let~ balances :=
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply
                              (Ty.path "alloc::vec::Vec")
                              []
                              [ Ty.path "u128"; Ty.path "alloc::alloc::Global" ],
                            "new",
                            []
                          |),
                          []
                        |)
                      |) in
                    let~ _ :=
                      M.use
                        (M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::collect::IntoIterator",
                                impl_IntoIterator_Item___Address_,
                                [],
                                "into_iter",
                                []
                              |),
                              [ M.read (| addresses |) ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let iter := M.copy (| γ |) in
                                M.loop (|
                                  ltac:(M.monadic
                                    (let~ _ :=
                                      M.match_operator (|
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::iter::traits::iterator::Iterator",
                                              Ty.associated,
                                              [],
                                              "next",
                                              []
                                            |),
                                            [ iter ]
                                          |)
                                        |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let _ :=
                                                M.is_struct_tuple (|
                                                  γ,
                                                  "core::option::Option::None"
                                                |) in
                                              M.alloc (|
                                                M.never_to_any (| M.read (| M.break (||) |) |)
                                              |)));
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ0_0 :=
                                                M.SubPointer.get_struct_tuple_field (|
                                                  γ,
                                                  "core::option::Option::Some",
                                                  0
                                                |) in
                                              let address := M.copy (| γ0_0 |) in
                                              let~ original_account :=
                                                M.copy (|
                                                  M.match_operator (|
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_trait_method (|
                                                          "core::ops::try_trait::Try",
                                                          Ty.apply
                                                            (Ty.path "core::result::Result")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path "&mut")
                                                                []
                                                                [
                                                                  Ty.path
                                                                    "revm::db::states::cache_account::CacheAccount"
                                                                ];
                                                              Ty.associated
                                                            ],
                                                          [],
                                                          "branch",
                                                          []
                                                        |),
                                                        [
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path
                                                                  "revm::db::states::state::State")
                                                                []
                                                                [ DB ],
                                                              "load_cache_account",
                                                              []
                                                            |),
                                                            [
                                                              M.read (| self |);
                                                              M.read (| address |)
                                                            ]
                                                          |)
                                                        ]
                                                      |)
                                                    |),
                                                    [
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (let γ0_0 :=
                                                            M.SubPointer.get_struct_tuple_field (|
                                                              γ,
                                                              "core::ops::control_flow::ControlFlow::Break",
                                                              0
                                                            |) in
                                                          let residual := M.copy (| γ0_0 |) in
                                                          M.alloc (|
                                                            M.never_to_any (|
                                                              M.read (|
                                                                M.return_ (|
                                                                  M.call_closure (|
                                                                    M.get_trait_method (|
                                                                      "core::ops::try_trait::FromResidual",
                                                                      Ty.apply
                                                                        (Ty.path
                                                                          "core::result::Result")
                                                                        []
                                                                        [
                                                                          Ty.apply
                                                                            (Ty.path
                                                                              "alloc::vec::Vec")
                                                                            []
                                                                            [
                                                                              Ty.path "u128";
                                                                              Ty.path
                                                                                "alloc::alloc::Global"
                                                                            ];
                                                                          Ty.associated
                                                                        ],
                                                                      [
                                                                        Ty.apply
                                                                          (Ty.path
                                                                            "core::result::Result")
                                                                          []
                                                                          [
                                                                            Ty.path
                                                                              "core::convert::Infallible";
                                                                            Ty.associated
                                                                          ]
                                                                      ],
                                                                      "from_residual",
                                                                      []
                                                                    |),
                                                                    [ M.read (| residual |) ]
                                                                  |)
                                                                |)
                                                              |)
                                                            |)
                                                          |)));
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (let γ0_0 :=
                                                            M.SubPointer.get_struct_tuple_field (|
                                                              γ,
                                                              "core::ops::control_flow::ControlFlow::Continue",
                                                              0
                                                            |) in
                                                          let val := M.copy (| γ0_0 |) in
                                                          val))
                                                    ]
                                                  |)
                                                |) in
                                              M.match_operator (|
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.path
                                                        "revm::db::states::cache_account::CacheAccount",
                                                      "drain_balance",
                                                      []
                                                    |),
                                                    [ M.read (| original_account |) ]
                                                  |)
                                                |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ0_0 :=
                                                        M.SubPointer.get_tuple_field (| γ, 0 |) in
                                                      let γ0_1 :=
                                                        M.SubPointer.get_tuple_field (| γ, 1 |) in
                                                      let balance := M.copy (| γ0_0 |) in
                                                      let transition := M.copy (| γ0_1 |) in
                                                      let~ _ :=
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path "alloc::vec::Vec")
                                                                []
                                                                [
                                                                  Ty.path "u128";
                                                                  Ty.path "alloc::alloc::Global"
                                                                ],
                                                              "push",
                                                              []
                                                            |),
                                                            [ balances; M.read (| balance |) ]
                                                          |)
                                                        |) in
                                                      M.alloc (|
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.apply
                                                              (Ty.path "alloc::vec::Vec")
                                                              []
                                                              [
                                                                Ty.tuple
                                                                  [
                                                                    Ty.path
                                                                      "alloy_primitives::bits::address::Address";
                                                                    Ty.path
                                                                      "revm::db::states::transition_account::TransitionAccount"
                                                                  ];
                                                                Ty.path "alloc::alloc::Global"
                                                              ],
                                                            "push",
                                                            []
                                                          |),
                                                          [
                                                            transitions;
                                                            Value.Tuple
                                                              [
                                                                M.read (| address |);
                                                                M.read (| transition |)
                                                              ]
                                                          ]
                                                        |)
                                                      |)))
                                                ]
                                              |)))
                                        ]
                                      |) in
                                    M.alloc (| Value.Tuple [] |)))
                                |)))
                          ]
                        |)) in
                    let~ _ :=
                      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 "core::option::Option")
                                        []
                                        [
                                          Ty.path
                                            "revm::db::states::transition_state::TransitionState"
                                        ],
                                      "as_mut",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "revm::db::states::state::State",
                                        "transition_state"
                                      |)
                                    ]
                                  |)
                                |) in
                              let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let s := M.copy (| γ0_0 |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "revm::db::states::transition_state::TransitionState",
                                    "add_transitions",
                                    []
                                  |),
                                  [ M.read (| s |); M.read (| transitions |) ]
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    M.alloc (|
                      Value.StructTuple "core::result::Result::Ok" [ M.read (| balances |) ]
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_drain_balances :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "drain_balances" (drain_balances DB).
        
        (*
            pub fn set_state_clear_flag(&mut self, has_state_clear: bool) {
                self.cache.set_state_clear_flag(has_state_clear);
            }
        *)
        Definition set_state_clear_flag
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; has_state_clear ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let has_state_clear := M.alloc (| has_state_clear |) in
              M.read (|
                let~ _ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm::db::states::cache::CacheState",
                        "set_state_clear_flag",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "revm::db::states::state::State",
                          "cache"
                        |);
                        M.read (| has_state_clear |)
                      ]
                    |)
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_set_state_clear_flag :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "set_state_clear_flag" (set_state_clear_flag DB).
        
        (*
            pub fn insert_not_existing(&mut self, address: Address) {
                self.cache.insert_not_existing(address)
            }
        *)
        Definition insert_not_existing
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; address ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let address := M.alloc (| address |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "revm::db::states::cache::CacheState",
                  "insert_not_existing",
                  []
                |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "revm::db::states::state::State",
                    "cache"
                  |);
                  M.read (| address |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_insert_not_existing :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "insert_not_existing" (insert_not_existing DB).
        
        (*
            pub fn insert_account(&mut self, address: Address, info: AccountInfo) {
                self.cache.insert_account(address, info)
            }
        *)
        Definition insert_account
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; address; info ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let address := M.alloc (| address |) in
              let info := M.alloc (| info |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "revm::db::states::cache::CacheState",
                  "insert_account",
                  []
                |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "revm::db::states::state::State",
                    "cache"
                  |);
                  M.read (| address |);
                  M.read (| info |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_insert_account :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "insert_account" (insert_account DB).
        
        (*
            pub fn insert_account_with_storage(
                &mut self,
                address: Address,
                info: AccountInfo,
                storage: PlainStorage,
            ) {
                self.cache
                    .insert_account_with_storage(address, info, storage)
            }
        *)
        Definition insert_account_with_storage
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; address; info; storage ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let address := M.alloc (| address |) in
              let info := M.alloc (| info |) in
              let storage := M.alloc (| storage |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "revm::db::states::cache::CacheState",
                  "insert_account_with_storage",
                  []
                |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "revm::db::states::state::State",
                    "cache"
                  |);
                  M.read (| address |);
                  M.read (| info |);
                  M.read (| storage |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_insert_account_with_storage :
          forall (DB : Ty.t),
          M.IsAssociatedFunction
            (Self DB)
            "insert_account_with_storage"
            (insert_account_with_storage DB).
        
        (*
            pub fn apply_transition(&mut self, transitions: Vec<(Address, TransitionAccount)>) {
                // add transition to transition state.
                if let Some(s) = self.transition_state.as_mut() {
                    s.add_transitions(transitions)
                }
            }
        *)
        Definition apply_transition
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; transitions ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let transitions := M.alloc (| transitions |) 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 "core::option::Option")
                                  []
                                  [ Ty.path "revm::db::states::transition_state::TransitionState" ],
                                "as_mut",
                                []
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "revm::db::states::state::State",
                                  "transition_state"
                                |)
                              ]
                            |)
                          |) in
                        let γ0_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ,
                            "core::option::Option::Some",
                            0
                          |) in
                        let s := M.copy (| γ0_0 |) in
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "revm::db::states::transition_state::TransitionState",
                              "add_transitions",
                              []
                            |),
                            [ M.read (| s |); M.read (| transitions |) ]
                          |)
                        |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_apply_transition :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "apply_transition" (apply_transition DB).
        
        (*
            pub fn merge_transitions(&mut self, retention: BundleRetention) {
                if let Some(transition_state) = self.transition_state.as_mut().map(TransitionState::take) {
                    self.bundle_state
                        .apply_transitions_and_create_reverts(transition_state, retention);
                }
            }
        *)
        Definition merge_transitions
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; retention ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let retention := M.alloc (| retention |) 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 "core::option::Option")
                                  []
                                  [
                                    Ty.apply
                                      (Ty.path "&mut")
                                      []
                                      [
                                        Ty.path
                                          "revm::db::states::transition_state::TransitionState"
                                      ]
                                  ],
                                "map",
                                [
                                  Ty.path "revm::db::states::transition_state::TransitionState";
                                  Ty.function
                                    [
                                      Ty.apply
                                        (Ty.path "&mut")
                                        []
                                        [
                                          Ty.path
                                            "revm::db::states::transition_state::TransitionState"
                                        ]
                                    ]
                                    (Ty.path "revm::db::states::transition_state::TransitionState")
                                ]
                              |),
                              [
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply
                                      (Ty.path "core::option::Option")
                                      []
                                      [
                                        Ty.path
                                          "revm::db::states::transition_state::TransitionState"
                                      ],
                                    "as_mut",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "revm::db::states::state::State",
                                      "transition_state"
                                    |)
                                  ]
                                |);
                                M.get_associated_function (|
                                  Ty.path "revm::db::states::transition_state::TransitionState",
                                  "take",
                                  []
                                |)
                              ]
                            |)
                          |) in
                        let γ0_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ,
                            "core::option::Option::Some",
                            0
                          |) in
                        let transition_state := M.copy (| γ0_0 |) in
                        let~ _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "revm::db::states::bundle_state::BundleState",
                                "apply_transitions_and_create_reverts",
                                []
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "revm::db::states::state::State",
                                  "bundle_state"
                                |);
                                M.read (| transition_state |);
                                M.read (| retention |)
                              ]
                            |)
                          |) in
                        M.alloc (| Value.Tuple [] |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_merge_transitions :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "merge_transitions" (merge_transitions DB).
        
        (*
            pub fn load_cache_account(&mut self, address: Address) -> Result<&mut CacheAccount, DB::Error> {
                match self.cache.accounts.entry(address) {
                    hash_map::Entry::Vacant(entry) => {
                        if self.use_preloaded_bundle {
                            // load account from bundle state
                            if let Some(account) =
                                self.bundle_state.account(&address).cloned().map(Into::into)
                            {
                                return Ok(entry.insert(account));
                            }
                        }
                        // if not found in bundle, load it from database
                        let info = self.database.basic(address)?;
                        let account = match info {
                            None => CacheAccount::new_loaded_not_existing(),
                            Some(acc) if acc.is_empty() => {
                                CacheAccount::new_loaded_empty_eip161(HashMap::new())
                            }
                            Some(acc) => CacheAccount::new_loaded(acc, HashMap::new()),
                        };
                        Ok(entry.insert(account))
                    }
                    hash_map::Entry::Occupied(entry) => Ok(entry.into_mut()),
                }
            }
        *)
        Definition load_cache_account
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; address ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let address := M.alloc (| address |) in
              M.catch_return (|
                ltac:(M.monadic
                  (M.read (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply
                              (Ty.path "std::collections::hash::map::HashMap")
                              []
                              [
                                Ty.path "alloy_primitives::bits::address::Address";
                                Ty.path "revm::db::states::cache_account::CacheAccount";
                                Ty.path "std::hash::random::RandomState"
                              ],
                            "entry",
                            []
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "revm::db::states::state::State",
                                "cache"
                              |),
                              "revm::db::states::cache::CacheState",
                              "accounts"
                            |);
                            M.read (| address |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "std::collections::hash::map::Entry::Vacant",
                                0
                              |) in
                            let entry := M.copy (| γ0_0 |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "revm::db::states::state::State",
                                            "use_preloaded_bundle"
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.match_operator (|
                                        M.alloc (| Value.Tuple [] |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ :=
                                                M.alloc (|
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.apply
                                                        (Ty.path "core::option::Option")
                                                        []
                                                        [
                                                          Ty.path
                                                            "revm::db::states::bundle_account::BundleAccount"
                                                        ],
                                                      "map",
                                                      [
                                                        Ty.path
                                                          "revm::db::states::cache_account::CacheAccount";
                                                        Ty.function
                                                          [
                                                            Ty.path
                                                              "revm::db::states::bundle_account::BundleAccount"
                                                          ]
                                                          (Ty.path
                                                            "revm::db::states::cache_account::CacheAccount")
                                                      ]
                                                    |),
                                                    [
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.apply
                                                            (Ty.path "core::option::Option")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path "&")
                                                                []
                                                                [
                                                                  Ty.path
                                                                    "revm::db::states::bundle_account::BundleAccount"
                                                                ]
                                                            ],
                                                          "cloned",
                                                          []
                                                        |),
                                                        [
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path
                                                                "revm::db::states::bundle_state::BundleState",
                                                              "account",
                                                              []
                                                            |),
                                                            [
                                                              M.SubPointer.get_struct_record_field (|
                                                                M.read (| self |),
                                                                "revm::db::states::state::State",
                                                                "bundle_state"
                                                              |);
                                                              address
                                                            ]
                                                          |)
                                                        ]
                                                      |);
                                                      M.get_trait_method (|
                                                        "core::convert::Into",
                                                        Ty.path
                                                          "revm::db::states::bundle_account::BundleAccount",
                                                        [
                                                          Ty.path
                                                            "revm::db::states::cache_account::CacheAccount"
                                                        ],
                                                        "into",
                                                        []
                                                      |)
                                                    ]
                                                  |)
                                                |) in
                                              let γ0_0 :=
                                                M.SubPointer.get_struct_tuple_field (|
                                                  γ,
                                                  "core::option::Option::Some",
                                                  0
                                                |) in
                                              let account := M.copy (| γ0_0 |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    M.return_ (|
                                                      Value.StructTuple
                                                        "core::result::Result::Ok"
                                                        [
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path
                                                                  "std::collections::hash::map::VacantEntry")
                                                                []
                                                                [
                                                                  Ty.path
                                                                    "alloy_primitives::bits::address::Address";
                                                                  Ty.path
                                                                    "revm::db::states::cache_account::CacheAccount"
                                                                ],
                                                              "insert",
                                                              []
                                                            |),
                                                            [
                                                              M.read (| entry |);
                                                              M.read (| account |)
                                                            ]
                                                          |)
                                                        ]
                                                    |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                        ]
                                      |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            let~ info :=
                              M.copy (|
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::Try",
                                        Ty.apply
                                          (Ty.path "core::result::Result")
                                          []
                                          [
                                            Ty.apply
                                              (Ty.path "core::option::Option")
                                              []
                                              [ Ty.path "revm_primitives::state::AccountInfo" ];
                                            Ty.associated
                                          ],
                                        [],
                                        "branch",
                                        []
                                      |),
                                      [
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "revm_primitives::db::Database",
                                            DB,
                                            [],
                                            "basic",
                                            []
                                          |),
                                          [
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| self |),
                                              "revm::db::states::state::State",
                                              "database"
                                            |);
                                            M.read (| address |)
                                          ]
                                        |)
                                      ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::ops::control_flow::ControlFlow::Break",
                                            0
                                          |) in
                                        let residual := M.copy (| γ0_0 |) in
                                        M.alloc (|
                                          M.never_to_any (|
                                            M.read (|
                                              M.return_ (|
                                                M.call_closure (|
                                                  M.get_trait_method (|
                                                    "core::ops::try_trait::FromResidual",
                                                    Ty.apply
                                                      (Ty.path "core::result::Result")
                                                      []
                                                      [
                                                        Ty.apply
                                                          (Ty.path "&mut")
                                                          []
                                                          [
                                                            Ty.path
                                                              "revm::db::states::cache_account::CacheAccount"
                                                          ];
                                                        Ty.associated
                                                      ],
                                                    [
                                                      Ty.apply
                                                        (Ty.path "core::result::Result")
                                                        []
                                                        [
                                                          Ty.path "core::convert::Infallible";
                                                          Ty.associated
                                                        ]
                                                    ],
                                                    "from_residual",
                                                    []
                                                  |),
                                                  [ M.read (| residual |) ]
                                                |)
                                              |)
                                            |)
                                          |)
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::ops::control_flow::ControlFlow::Continue",
                                            0
                                          |) in
                                        let val := M.copy (| γ0_0 |) in
                                        val))
                                  ]
                                |)
                              |) in
                            let~ account :=
                              M.copy (|
                                M.match_operator (|
                                  info,
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path
                                                "revm::db::states::cache_account::CacheAccount",
                                              "new_loaded_not_existing",
                                              []
                                            |),
                                            []
                                          |)
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let acc := M.copy (| γ0_0 |) in
                                        let γ :=
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "revm_primitives::state::AccountInfo",
                                                "is_empty",
                                                []
                                              |),
                                              [ acc ]
                                            |)
                                          |) in
                                        let _ :=
                                          M.is_constant_or_break_match (|
                                            M.read (| γ |),
                                            Value.Bool true
                                          |) in
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path
                                                "revm::db::states::cache_account::CacheAccount",
                                              "new_loaded_empty_eip161",
                                              []
                                            |),
                                            [
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.apply
                                                    (Ty.path "std::collections::hash::map::HashMap")
                                                    []
                                                    [
                                                      Ty.apply
                                                        (Ty.path "ruint::Uint")
                                                        [
                                                          Value.Integer IntegerKind.Usize 256;
                                                          Value.Integer IntegerKind.Usize 4
                                                        ]
                                                        [];
                                                      Ty.apply
                                                        (Ty.path "ruint::Uint")
                                                        [
                                                          Value.Integer IntegerKind.Usize 256;
                                                          Value.Integer IntegerKind.Usize 4
                                                        ]
                                                        [];
                                                      Ty.path "std::hash::random::RandomState"
                                                    ],
                                                  "new",
                                                  []
                                                |),
                                                []
                                              |)
                                            ]
                                          |)
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let acc := M.copy (| γ0_0 |) in
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path
                                                "revm::db::states::cache_account::CacheAccount",
                                              "new_loaded",
                                              []
                                            |),
                                            [
                                              M.read (| acc |);
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.apply
                                                    (Ty.path "std::collections::hash::map::HashMap")
                                                    []
                                                    [
                                                      Ty.apply
                                                        (Ty.path "ruint::Uint")
                                                        [
                                                          Value.Integer IntegerKind.Usize 256;
                                                          Value.Integer IntegerKind.Usize 4
                                                        ]
                                                        [];
                                                      Ty.apply
                                                        (Ty.path "ruint::Uint")
                                                        [
                                                          Value.Integer IntegerKind.Usize 256;
                                                          Value.Integer IntegerKind.Usize 4
                                                        ]
                                                        [];
                                                      Ty.path "std::hash::random::RandomState"
                                                    ],
                                                  "new",
                                                  []
                                                |),
                                                []
                                              |)
                                            ]
                                          |)
                                        |)))
                                  ]
                                |)
                              |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::result::Result::Ok"
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "std::collections::hash::map::VacantEntry")
                                        []
                                        [
                                          Ty.path "alloy_primitives::bits::address::Address";
                                          Ty.path "revm::db::states::cache_account::CacheAccount"
                                        ],
                                      "insert",
                                      []
                                    |),
                                    [ M.read (| entry |); M.read (| account |) ]
                                  |)
                                ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "std::collections::hash::map::Entry::Occupied",
                                0
                              |) in
                            let entry := M.copy (| γ0_0 |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::result::Result::Ok"
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "std::collections::hash::map::OccupiedEntry")
                                        []
                                        [
                                          Ty.path "alloy_primitives::bits::address::Address";
                                          Ty.path "revm::db::states::cache_account::CacheAccount"
                                        ],
                                      "into_mut",
                                      []
                                    |),
                                    [ M.read (| entry |) ]
                                  |)
                                ]
                            |)))
                      ]
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_load_cache_account :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "load_cache_account" (load_cache_account DB).
        
        (*
            pub fn take_bundle(&mut self) -> BundleState {
                core::mem::take(&mut self.bundle_state)
            }
        *)
        Definition take_bundle
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              M.call_closure (|
                M.get_function (|
                  "core::mem::take",
                  [ Ty.path "revm::db::states::bundle_state::BundleState" ]
                |),
                [
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "revm::db::states::state::State",
                    "bundle_state"
                  |)
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom AssociatedFunction_take_bundle :
          forall (DB : Ty.t),
          M.IsAssociatedFunction (Self DB) "take_bundle" (take_bundle DB).
      End Impl_revm_db_states_state_State_DB.
      
      Module Impl_revm_primitives_db_Database_where_revm_primitives_db_Database_DB_for_revm_db_states_state_State_DB.
        Definition Self (DB : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "revm::db::states::state::State") [] [ DB ].
        
        (*     type Error = DB::Error; *)
        Definition _Error (DB : Ty.t) : Ty.t := Ty.associated.
        
        (*
            fn basic(&mut self, address: Address) -> Result<Option<AccountInfo>, Self::Error> {
                self.load_cache_account(address).map(|a| a.account_info())
            }
        *)
        Definition basic (DB : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; address ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let address := M.alloc (| address |) in
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply
                    (Ty.path "core::result::Result")
                    []
                    [
                      Ty.apply
                        (Ty.path "&mut")
                        []
                        [ Ty.path "revm::db::states::cache_account::CacheAccount" ];
                      Ty.associated
                    ],
                  "map",
                  [
                    Ty.apply
                      (Ty.path "core::option::Option")
                      []
                      [ Ty.path "revm_primitives::state::AccountInfo" ];
                    Ty.function
                      [
                        Ty.tuple
                          [
                            Ty.apply
                              (Ty.path "&mut")
                              []
                              [ Ty.path "revm::db::states::cache_account::CacheAccount" ]
                          ]
                      ]
                      (Ty.apply
                        (Ty.path "core::option::Option")
                        []
                        [ Ty.path "revm_primitives::state::AccountInfo" ])
                  ]
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply (Ty.path "revm::db::states::state::State") [] [ DB ],
                      "load_cache_account",
                      []
                    |),
                    [ M.read (| self |); M.read (| address |) ]
                  |);
                  M.closure
                    (fun γ =>
                      ltac:(M.monadic
                        match γ with
                        | [ α0 ] =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| α0 |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let a := M.copy (| γ |) in
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "revm::db::states::cache_account::CacheAccount",
                                        "account_info",
                                        []
                                      |),
                                      [ M.read (| a |) ]
                                    |)))
                              ]
                            |)))
                        | _ => M.impossible "wrong number of arguments"
                        end))
                ]
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn code_by_hash(&mut self, code_hash: B256) -> Result<Bytecode, Self::Error> {
                let res = match self.cache.contracts.entry(code_hash) {
                    hash_map::Entry::Occupied(entry) => Ok(entry.get().clone()),
                    hash_map::Entry::Vacant(entry) => {
                        if self.use_preloaded_bundle {
                            if let Some(code) = self.bundle_state.contracts.get(&code_hash) {
                                entry.insert(code.clone());
                                return Ok(code.clone());
                            }
                        }
                        // if not found in bundle ask database
                        let code = self.database.code_by_hash(code_hash)?;
                        entry.insert(code.clone());
                        Ok(code)
                    }
                };
                res
            }
        *)
        Definition code_by_hash
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; code_hash ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let code_hash := M.alloc (| code_hash |) in
              M.catch_return (|
                ltac:(M.monadic
                  (M.read (|
                    let~ res :=
                      M.copy (|
                        M.match_operator (|
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "std::collections::hash::map::HashMap")
                                  []
                                  [
                                    Ty.apply
                                      (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                                      [ Value.Integer IntegerKind.Usize 32 ]
                                      [];
                                    Ty.path "revm_primitives::bytecode::Bytecode";
                                    Ty.path "std::hash::random::RandomState"
                                  ],
                                "entry",
                                []
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "revm::db::states::state::State",
                                    "cache"
                                  |),
                                  "revm::db::states::cache::CacheState",
                                  "contracts"
                                |);
                                M.read (| code_hash |)
                              ]
                            |)
                          |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "std::collections::hash::map::Entry::Occupied",
                                    0
                                  |) in
                                let entry := M.copy (| γ0_0 |) in
                                M.alloc (|
                                  Value.StructTuple
                                    "core::result::Result::Ok"
                                    [
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::clone::Clone",
                                          Ty.path "revm_primitives::bytecode::Bytecode",
                                          [],
                                          "clone",
                                          []
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply
                                                (Ty.path
                                                  "std::collections::hash::map::OccupiedEntry")
                                                []
                                                [
                                                  Ty.apply
                                                    (Ty.path
                                                      "alloy_primitives::bits::fixed::FixedBytes")
                                                    [ Value.Integer IntegerKind.Usize 32 ]
                                                    [];
                                                  Ty.path "revm_primitives::bytecode::Bytecode"
                                                ],
                                              "get",
                                              []
                                            |),
                                            [ entry ]
                                          |)
                                        ]
                                      |)
                                    ]
                                |)));
                            fun γ =>
                              ltac:(M.monadic
                                (let γ0_0 :=
                                  M.SubPointer.get_struct_tuple_field (|
                                    γ,
                                    "std::collections::hash::map::Entry::Vacant",
                                    0
                                  |) in
                                let entry := M.copy (| γ0_0 |) in
                                let~ _ :=
                                  M.match_operator (|
                                    M.alloc (| Value.Tuple [] |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ :=
                                            M.use
                                              (M.SubPointer.get_struct_record_field (|
                                                M.read (| self |),
                                                "revm::db::states::state::State",
                                                "use_preloaded_bundle"
                                              |)) in
                                          let _ :=
                                            M.is_constant_or_break_match (|
                                              M.read (| γ |),
                                              Value.Bool true
                                            |) in
                                          M.match_operator (|
                                            M.alloc (| Value.Tuple [] |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ :=
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.apply
                                                            (Ty.path
                                                              "std::collections::hash::map::HashMap")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path
                                                                  "alloy_primitives::bits::fixed::FixedBytes")
                                                                [ Value.Integer IntegerKind.Usize 32
                                                                ]
                                                                [];
                                                              Ty.path
                                                                "revm_primitives::bytecode::Bytecode";
                                                              Ty.path
                                                                "std::hash::random::RandomState"
                                                            ],
                                                          "get",
                                                          [
                                                            Ty.apply
                                                              (Ty.path
                                                                "alloy_primitives::bits::fixed::FixedBytes")
                                                              [ Value.Integer IntegerKind.Usize 32 ]
                                                              []
                                                          ]
                                                        |),
                                                        [
                                                          M.SubPointer.get_struct_record_field (|
                                                            M.SubPointer.get_struct_record_field (|
                                                              M.read (| self |),
                                                              "revm::db::states::state::State",
                                                              "bundle_state"
                                                            |),
                                                            "revm::db::states::bundle_state::BundleState",
                                                            "contracts"
                                                          |);
                                                          code_hash
                                                        ]
                                                      |)
                                                    |) in
                                                  let γ0_0 :=
                                                    M.SubPointer.get_struct_tuple_field (|
                                                      γ,
                                                      "core::option::Option::Some",
                                                      0
                                                    |) in
                                                  let code := M.copy (| γ0_0 |) in
                                                  M.alloc (|
                                                    M.never_to_any (|
                                                      M.read (|
                                                        let~ _ :=
                                                          M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.apply
                                                                  (Ty.path
                                                                    "std::collections::hash::map::VacantEntry")
                                                                  []
                                                                  [
                                                                    Ty.apply
                                                                      (Ty.path
                                                                        "alloy_primitives::bits::fixed::FixedBytes")
                                                                      [
                                                                        Value.Integer
                                                                          IntegerKind.Usize
                                                                          32
                                                                      ]
                                                                      [];
                                                                    Ty.path
                                                                      "revm_primitives::bytecode::Bytecode"
                                                                  ],
                                                                "insert",
                                                                []
                                                              |),
                                                              [
                                                                M.read (| entry |);
                                                                M.call_closure (|
                                                                  M.get_trait_method (|
                                                                    "core::clone::Clone",
                                                                    Ty.path
                                                                      "revm_primitives::bytecode::Bytecode",
                                                                    [],
                                                                    "clone",
                                                                    []
                                                                  |),
                                                                  [ M.read (| code |) ]
                                                                |)
                                                              ]
                                                            |)
                                                          |) in
                                                        M.return_ (|
                                                          Value.StructTuple
                                                            "core::result::Result::Ok"
                                                            [
                                                              M.call_closure (|
                                                                M.get_trait_method (|
                                                                  "core::clone::Clone",
                                                                  Ty.path
                                                                    "revm_primitives::bytecode::Bytecode",
                                                                  [],
                                                                  "clone",
                                                                  []
                                                                |),
                                                                [ M.read (| code |) ]
                                                              |)
                                                            ]
                                                        |)
                                                      |)
                                                    |)
                                                  |)));
                                              fun γ =>
                                                ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                            ]
                                          |)));
                                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                    ]
                                  |) in
                                let~ code :=
                                  M.copy (|
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::ops::try_trait::Try",
                                            Ty.apply
                                              (Ty.path "core::result::Result")
                                              []
                                              [
                                                Ty.path "revm_primitives::bytecode::Bytecode";
                                                Ty.associated
                                              ],
                                            [],
                                            "branch",
                                            []
                                          |),
                                          [
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "revm_primitives::db::Database",
                                                DB,
                                                [],
                                                "code_by_hash",
                                                []
                                              |),
                                              [
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| self |),
                                                  "revm::db::states::state::State",
                                                  "database"
                                                |);
                                                M.read (| code_hash |)
                                              ]
                                            |)
                                          ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::ops::control_flow::ControlFlow::Break",
                                                0
                                              |) in
                                            let residual := M.copy (| γ0_0 |) in
                                            M.alloc (|
                                              M.never_to_any (|
                                                M.read (|
                                                  M.return_ (|
                                                    M.call_closure (|
                                                      M.get_trait_method (|
                                                        "core::ops::try_trait::FromResidual",
                                                        Ty.apply
                                                          (Ty.path "core::result::Result")
                                                          []
                                                          [
                                                            Ty.path
                                                              "revm_primitives::bytecode::Bytecode";
                                                            Ty.associated
                                                          ],
                                                        [
                                                          Ty.apply
                                                            (Ty.path "core::result::Result")
                                                            []
                                                            [
                                                              Ty.path "core::convert::Infallible";
                                                              Ty.associated
                                                            ]
                                                        ],
                                                        "from_residual",
                                                        []
                                                      |),
                                                      [ M.read (| residual |) ]
                                                    |)
                                                  |)
                                                |)
                                              |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::ops::control_flow::ControlFlow::Continue",
                                                0
                                              |) in
                                            let val := M.copy (| γ0_0 |) in
                                            val))
                                      ]
                                    |)
                                  |) in
                                let~ _ :=
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply
                                          (Ty.path "std::collections::hash::map::VacantEntry")
                                          []
                                          [
                                            Ty.apply
                                              (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                                              [ Value.Integer IntegerKind.Usize 32 ]
                                              [];
                                            Ty.path "revm_primitives::bytecode::Bytecode"
                                          ],
                                        "insert",
                                        []
                                      |),
                                      [
                                        M.read (| entry |);
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::clone::Clone",
                                            Ty.path "revm_primitives::bytecode::Bytecode",
                                            [],
                                            "clone",
                                            []
                                          |),
                                          [ code ]
                                        |)
                                      ]
                                    |)
                                  |) in
                                M.alloc (|
                                  Value.StructTuple "core::result::Result::Ok" [ M.read (| code |) ]
                                |)))
                          ]
                        |)
                      |) in
                    res
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn storage(&mut self, address: Address, index: U256) -> Result<U256, Self::Error> {
                // Account is guaranteed to be loaded.
                // Note that storage from bundle is already loaded with account.
                if let Some(account) = self.cache.accounts.get_mut(&address) {
                    // account will always be some, but if it is not, U256::ZERO will be returned.
                    let is_storage_known = account.status.is_storage_known();
                    Ok(account
                        .account
                        .as_mut()
                        .map(|account| match account.storage.entry(index) {
                            hash_map::Entry::Occupied(entry) => Ok( *entry.get()),
                            hash_map::Entry::Vacant(entry) => {
                                // if account was destroyed or account is newly built
                                // we return zero and don't ask database.
                                let value = if is_storage_known {
                                    U256::ZERO
                                } else {
                                    self.database.storage(address, index)?
                                };
                                entry.insert(value);
                                Ok(value)
                            }
                        })
                        .transpose()?
                        .unwrap_or_default())
                } else {
                    unreachable!("For accessing any storage account is guaranteed to be loaded beforehand")
                }
            }
        *)
        Definition storage (DB : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; address; index ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let address := M.alloc (| address |) in
              let index := M.alloc (| index |) in
              M.catch_return (|
                ltac:(M.monadic
                  (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 "std::collections::hash::map::HashMap")
                                      []
                                      [
                                        Ty.path "alloy_primitives::bits::address::Address";
                                        Ty.path "revm::db::states::cache_account::CacheAccount";
                                        Ty.path "std::hash::random::RandomState"
                                      ],
                                    "get_mut",
                                    [ Ty.path "alloy_primitives::bits::address::Address" ]
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "revm::db::states::state::State",
                                        "cache"
                                      |),
                                      "revm::db::states::cache::CacheState",
                                      "accounts"
                                    |);
                                    address
                                  ]
                                |)
                              |) in
                            let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let account := M.copy (| γ0_0 |) in
                            let~ is_storage_known :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "revm::db::states::account_status::AccountStatus",
                                    "is_storage_known",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| account |),
                                      "revm::db::states::cache_account::CacheAccount",
                                      "status"
                                    |)
                                  ]
                                |)
                              |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::result::Result::Ok"
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "core::option::Option")
                                        []
                                        [
                                          Ty.apply
                                            (Ty.path "ruint::Uint")
                                            [
                                              Value.Integer IntegerKind.Usize 256;
                                              Value.Integer IntegerKind.Usize 4
                                            ]
                                            []
                                        ],
                                      "unwrap_or_default",
                                      []
                                    |),
                                    [
                                      M.read (|
                                        M.match_operator (|
                                          M.alloc (|
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::ops::try_trait::Try",
                                                Ty.apply
                                                  (Ty.path "core::result::Result")
                                                  []
                                                  [
                                                    Ty.apply
                                                      (Ty.path "core::option::Option")
                                                      []
                                                      [
                                                        Ty.apply
                                                          (Ty.path "ruint::Uint")
                                                          [
                                                            Value.Integer IntegerKind.Usize 256;
                                                            Value.Integer IntegerKind.Usize 4
                                                          ]
                                                          []
                                                      ];
                                                    Ty.associated
                                                  ],
                                                [],
                                                "branch",
                                                []
                                              |),
                                              [
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path "core::option::Option")
                                                      []
                                                      [
                                                        Ty.apply
                                                          (Ty.path "core::result::Result")
                                                          []
                                                          [
                                                            Ty.apply
                                                              (Ty.path "ruint::Uint")
                                                              [
                                                                Value.Integer IntegerKind.Usize 256;
                                                                Value.Integer IntegerKind.Usize 4
                                                              ]
                                                              [];
                                                            Ty.associated
                                                          ]
                                                      ],
                                                    "transpose",
                                                    []
                                                  |),
                                                  [
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.apply
                                                          (Ty.path "core::option::Option")
                                                          []
                                                          [
                                                            Ty.apply
                                                              (Ty.path "&mut")
                                                              []
                                                              [
                                                                Ty.path
                                                                  "revm::db::states::plain_account::PlainAccount"
                                                              ]
                                                          ],
                                                        "map",
                                                        [
                                                          Ty.apply
                                                            (Ty.path "core::result::Result")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path "ruint::Uint")
                                                                [
                                                                  Value.Integer
                                                                    IntegerKind.Usize
                                                                    256;
                                                                  Value.Integer IntegerKind.Usize 4
                                                                ]
                                                                [];
                                                              Ty.associated
                                                            ];
                                                          Ty.function
                                                            [
                                                              Ty.tuple
                                                                [
                                                                  Ty.apply
                                                                    (Ty.path "&mut")
                                                                    []
                                                                    [
                                                                      Ty.path
                                                                        "revm::db::states::plain_account::PlainAccount"
                                                                    ]
                                                                ]
                                                            ]
                                                            (Ty.apply
                                                              (Ty.path "core::result::Result")
                                                              []
                                                              [
                                                                Ty.apply
                                                                  (Ty.path "ruint::Uint")
                                                                  [
                                                                    Value.Integer
                                                                      IntegerKind.Usize
                                                                      256;
                                                                    Value.Integer
                                                                      IntegerKind.Usize
                                                                      4
                                                                  ]
                                                                  [];
                                                                Ty.associated
                                                              ])
                                                        ]
                                                      |),
                                                      [
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.apply
                                                              (Ty.path "core::option::Option")
                                                              []
                                                              [
                                                                Ty.path
                                                                  "revm::db::states::plain_account::PlainAccount"
                                                              ],
                                                            "as_mut",
                                                            []
                                                          |),
                                                          [
                                                            M.SubPointer.get_struct_record_field (|
                                                              M.read (| account |),
                                                              "revm::db::states::cache_account::CacheAccount",
                                                              "account"
                                                            |)
                                                          ]
                                                        |);
                                                        M.closure
                                                          (fun γ =>
                                                            ltac:(M.monadic
                                                              match γ with
                                                              | [ α0 ] =>
                                                                ltac:(M.monadic
                                                                  (M.match_operator (|
                                                                    M.alloc (| α0 |),
                                                                    [
                                                                      fun γ =>
                                                                        ltac:(M.monadic
                                                                          (let account :=
                                                                            M.copy (| γ |) in
                                                                          M.read (|
                                                                            M.match_operator (|
                                                                              M.alloc (|
                                                                                M.call_closure (|
                                                                                  M.get_associated_function (|
                                                                                    Ty.apply
                                                                                      (Ty.path
                                                                                        "std::collections::hash::map::HashMap")
                                                                                      []
                                                                                      [
                                                                                        Ty.apply
                                                                                          (Ty.path
                                                                                            "ruint::Uint")
                                                                                          [
                                                                                            Value.Integer
                                                                                              IntegerKind.Usize
                                                                                              256;
                                                                                            Value.Integer
                                                                                              IntegerKind.Usize
                                                                                              4
                                                                                          ]
                                                                                          [];
                                                                                        Ty.apply
                                                                                          (Ty.path
                                                                                            "ruint::Uint")
                                                                                          [
                                                                                            Value.Integer
                                                                                              IntegerKind.Usize
                                                                                              256;
                                                                                            Value.Integer
                                                                                              IntegerKind.Usize
                                                                                              4
                                                                                          ]
                                                                                          [];
                                                                                        Ty.path
                                                                                          "std::hash::random::RandomState"
                                                                                      ],
                                                                                    "entry",
                                                                                    []
                                                                                  |),
                                                                                  [
                                                                                    M.SubPointer.get_struct_record_field (|
                                                                                      M.read (|
                                                                                        account
                                                                                      |),
                                                                                      "revm::db::states::plain_account::PlainAccount",
                                                                                      "storage"
                                                                                    |);
                                                                                    M.read (|
                                                                                      index
                                                                                    |)
                                                                                  ]
                                                                                |)
                                                                              |),
                                                                              [
                                                                                fun γ =>
                                                                                  ltac:(M.monadic
                                                                                    (let γ0_0 :=
                                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                                        γ,
                                                                                        "std::collections::hash::map::Entry::Occupied",
                                                                                        0
                                                                                      |) in
                                                                                    let entry :=
                                                                                      M.copy (|
                                                                                        γ0_0
                                                                                      |) in
                                                                                    M.alloc (|
                                                                                      Value.StructTuple
                                                                                        "core::result::Result::Ok"
                                                                                        [
                                                                                          M.read (|
                                                                                            M.call_closure (|
                                                                                              M.get_associated_function (|
                                                                                                Ty.apply
                                                                                                  (Ty.path
                                                                                                    "std::collections::hash::map::OccupiedEntry")
                                                                                                  []
                                                                                                  [
                                                                                                    Ty.apply
                                                                                                      (Ty.path
                                                                                                        "ruint::Uint")
                                                                                                      [
                                                                                                        Value.Integer
                                                                                                          IntegerKind.Usize
                                                                                                          256;
                                                                                                        Value.Integer
                                                                                                          IntegerKind.Usize
                                                                                                          4
                                                                                                      ]
                                                                                                      [];
                                                                                                    Ty.apply
                                                                                                      (Ty.path
                                                                                                        "ruint::Uint")
                                                                                                      [
                                                                                                        Value.Integer
                                                                                                          IntegerKind.Usize
                                                                                                          256;
                                                                                                        Value.Integer
                                                                                                          IntegerKind.Usize
                                                                                                          4
                                                                                                      ]
                                                                                                      []
                                                                                                  ],
                                                                                                "get",
                                                                                                []
                                                                                              |),
                                                                                              [
                                                                                                entry
                                                                                              ]
                                                                                            |)
                                                                                          |)
                                                                                        ]
                                                                                    |)));
                                                                                fun γ =>
                                                                                  ltac:(M.monadic
                                                                                    (let γ0_0 :=
                                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                                        γ,
                                                                                        "std::collections::hash::map::Entry::Vacant",
                                                                                        0
                                                                                      |) in
                                                                                    let entry :=
                                                                                      M.copy (|
                                                                                        γ0_0
                                                                                      |) in
                                                                                    let~ value :=
                                                                                      M.copy (|
                                                                                        M.match_operator (|
                                                                                          M.alloc (|
                                                                                            Value.Tuple
                                                                                              []
                                                                                          |),
                                                                                          [
                                                                                            fun γ =>
                                                                                              ltac:(M.monadic
                                                                                                (let
                                                                                                      γ :=
                                                                                                  M.use
                                                                                                    is_storage_known in
                                                                                                let
                                                                                                      _ :=
                                                                                                  M.is_constant_or_break_match (|
                                                                                                    M.read (|
                                                                                                      γ
                                                                                                    |),
                                                                                                    Value.Bool
                                                                                                      true
                                                                                                  |) in
                                                                                                M.get_constant (|
                                                                                                  "ruint::ZERO"
                                                                                                |)));
                                                                                            fun γ =>
                                                                                              ltac:(M.monadic
                                                                                                (M.match_operator (|
                                                                                                  M.alloc (|
                                                                                                    M.call_closure (|
                                                                                                      M.get_trait_method (|
                                                                                                        "core::ops::try_trait::Try",
                                                                                                        Ty.apply
                                                                                                          (Ty.path
                                                                                                            "core::result::Result")
                                                                                                          []
                                                                                                          [
                                                                                                            Ty.apply
                                                                                                              (Ty.path
                                                                                                                "ruint::Uint")
                                                                                                              [
                                                                                                                Value.Integer
                                                                                                                  IntegerKind.Usize
                                                                                                                  256;
                                                                                                                Value.Integer
                                                                                                                  IntegerKind.Usize
                                                                                                                  4
                                                                                                              ]
                                                                                                              [];
                                                                                                            Ty.associated
                                                                                                          ],
                                                                                                        [],
                                                                                                        "branch",
                                                                                                        []
                                                                                                      |),
                                                                                                      [
                                                                                                        M.call_closure (|
                                                                                                          M.get_trait_method (|
                                                                                                            "revm_primitives::db::Database",
                                                                                                            DB,
                                                                                                            [],
                                                                                                            "storage",
                                                                                                            []
                                                                                                          |),
                                                                                                          [
                                                                                                            M.SubPointer.get_struct_record_field (|
                                                                                                              M.read (|
                                                                                                                self
                                                                                                              |),
                                                                                                              "revm::db::states::state::State",
                                                                                                              "database"
                                                                                                            |);
                                                                                                            M.read (|
                                                                                                              address
                                                                                                            |);
                                                                                                            M.read (|
                                                                                                              index
                                                                                                            |)
                                                                                                          ]
                                                                                                        |)
                                                                                                      ]
                                                                                                    |)
                                                                                                  |),
                                                                                                  [
                                                                                                    fun
                                                                                                        γ =>
                                                                                                      ltac:(M.monadic
                                                                                                        (let
                                                                                                              γ0_0 :=
                                                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                                                            γ,
                                                                                                            "core::ops::control_flow::ControlFlow::Break",
                                                                                                            0
                                                                                                          |) in
                                                                                                        let
                                                                                                              residual :=
                                                                                                          M.copy (|
                                                                                                            γ0_0
                                                                                                          |) in
                                                                                                        M.alloc (|
                                                                                                          M.never_to_any (|
                                                                                                            M.read (|
                                                                                                              M.return_ (|
                                                                                                                M.call_closure (|
                                                                                                                  M.get_trait_method (|
                                                                                                                    "core::ops::try_trait::FromResidual",
                                                                                                                    Ty.apply
                                                                                                                      (Ty.path
                                                                                                                        "core::result::Result")
                                                                                                                      []
                                                                                                                      [
                                                                                                                        Ty.apply
                                                                                                                          (Ty.path
                                                                                                                            "ruint::Uint")
                                                                                                                          [
                                                                                                                            Value.Integer
                                                                                                                              IntegerKind.Usize
                                                                                                                              256;
                                                                                                                            Value.Integer
                                                                                                                              IntegerKind.Usize
                                                                                                                              4
                                                                                                                          ]
                                                                                                                          [];
                                                                                                                        Ty.associated
                                                                                                                      ],
                                                                                                                    [
                                                                                                                      Ty.apply
                                                                                                                        (Ty.path
                                                                                                                          "core::result::Result")
                                                                                                                        []
                                                                                                                        [
                                                                                                                          Ty.path
                                                                                                                            "core::convert::Infallible";
                                                                                                                          Ty.associated
                                                                                                                        ]
                                                                                                                    ],
                                                                                                                    "from_residual",
                                                                                                                    []
                                                                                                                  |),
                                                                                                                  [
                                                                                                                    M.read (|
                                                                                                                      residual
                                                                                                                    |)
                                                                                                                  ]
                                                                                                                |)
                                                                                                              |)
                                                                                                            |)
                                                                                                          |)
                                                                                                        |)));
                                                                                                    fun
                                                                                                        γ =>
                                                                                                      ltac:(M.monadic
                                                                                                        (let
                                                                                                              γ0_0 :=
                                                                                                          M.SubPointer.get_struct_tuple_field (|
                                                                                                            γ,
                                                                                                            "core::ops::control_flow::ControlFlow::Continue",
                                                                                                            0
                                                                                                          |) in
                                                                                                        let
                                                                                                              val :=
                                                                                                          M.copy (|
                                                                                                            γ0_0
                                                                                                          |) in
                                                                                                        val))
                                                                                                  ]
                                                                                                |)))
                                                                                          ]
                                                                                        |)
                                                                                      |) in
                                                                                    let~ _ :=
                                                                                      M.alloc (|
                                                                                        M.call_closure (|
                                                                                          M.get_associated_function (|
                                                                                            Ty.apply
                                                                                              (Ty.path
                                                                                                "std::collections::hash::map::VacantEntry")
                                                                                              []
                                                                                              [
                                                                                                Ty.apply
                                                                                                  (Ty.path
                                                                                                    "ruint::Uint")
                                                                                                  [
                                                                                                    Value.Integer
                                                                                                      IntegerKind.Usize
                                                                                                      256;
                                                                                                    Value.Integer
                                                                                                      IntegerKind.Usize
                                                                                                      4
                                                                                                  ]
                                                                                                  [];
                                                                                                Ty.apply
                                                                                                  (Ty.path
                                                                                                    "ruint::Uint")
                                                                                                  [
                                                                                                    Value.Integer
                                                                                                      IntegerKind.Usize
                                                                                                      256;
                                                                                                    Value.Integer
                                                                                                      IntegerKind.Usize
                                                                                                      4
                                                                                                  ]
                                                                                                  []
                                                                                              ],
                                                                                            "insert",
                                                                                            []
                                                                                          |),
                                                                                          [
                                                                                            M.read (|
                                                                                              entry
                                                                                            |);
                                                                                            M.read (|
                                                                                              value
                                                                                            |)
                                                                                          ]
                                                                                        |)
                                                                                      |) in
                                                                                    M.alloc (|
                                                                                      Value.StructTuple
                                                                                        "core::result::Result::Ok"
                                                                                        [
                                                                                          M.read (|
                                                                                            value
                                                                                          |)
                                                                                        ]
                                                                                    |)))
                                                                              ]
                                                                            |)
                                                                          |)))
                                                                    ]
                                                                  |)))
                                                              | _ =>
                                                                M.impossible
                                                                  "wrong number of arguments"
                                                              end))
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              ]
                                            |)
                                          |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ0_0 :=
                                                  M.SubPointer.get_struct_tuple_field (|
                                                    γ,
                                                    "core::ops::control_flow::ControlFlow::Break",
                                                    0
                                                  |) in
                                                let residual := M.copy (| γ0_0 |) in
                                                M.alloc (|
                                                  M.never_to_any (|
                                                    M.read (|
                                                      M.return_ (|
                                                        M.call_closure (|
                                                          M.get_trait_method (|
                                                            "core::ops::try_trait::FromResidual",
                                                            Ty.apply
                                                              (Ty.path "core::result::Result")
                                                              []
                                                              [
                                                                Ty.apply
                                                                  (Ty.path "ruint::Uint")
                                                                  [
                                                                    Value.Integer
                                                                      IntegerKind.Usize
                                                                      256;
                                                                    Value.Integer
                                                                      IntegerKind.Usize
                                                                      4
                                                                  ]
                                                                  [];
                                                                Ty.associated
                                                              ],
                                                            [
                                                              Ty.apply
                                                                (Ty.path "core::result::Result")
                                                                []
                                                                [
                                                                  Ty.path
                                                                    "core::convert::Infallible";
                                                                  Ty.associated
                                                                ]
                                                            ],
                                                            "from_residual",
                                                            []
                                                          |),
                                                          [ M.read (| residual |) ]
                                                        |)
                                                      |)
                                                    |)
                                                  |)
                                                |)));
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ0_0 :=
                                                  M.SubPointer.get_struct_tuple_field (|
                                                    γ,
                                                    "core::ops::control_flow::ControlFlow::Continue",
                                                    0
                                                  |) in
                                                let val := M.copy (| γ0_0 |) in
                                                val))
                                          ]
                                        |)
                                      |)
                                    ]
                                  |)
                                ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (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: For accessing any storage account is guaranteed to be loaded beforehand"
                                              |)
                                            ]
                                        |);
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.path "core::fmt::rt::Argument",
                                              "none",
                                              []
                                            |),
                                            []
                                          |)
                                        |)
                                      ]
                                    |)
                                  ]
                                |)
                              |)
                            |)))
                      ]
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        (*
            fn block_hash(&mut self, number: U256) -> Result<B256, Self::Error> {
                // block number is never bigger then u64::MAX.
                let u64num: u64 = number.to();
                match self.block_hashes.entry(u64num) {
                    btree_map::Entry::Occupied(entry) => Ok( *entry.get()),
                    btree_map::Entry::Vacant(entry) => {
                        let ret = *entry.insert(self.database.block_hash(number)?);
        
                        // prune all hashes that are older then BLOCK_HASH_HISTORY
                        while let Some(entry) = self.block_hashes.first_entry() {
                            if *entry.key() < u64num.saturating_sub(BLOCK_HASH_HISTORY as u64) {
                                entry.remove();
                            } else {
                                break;
                            }
                        }
        
                        Ok(ret)
                    }
                }
            }
        *)
        Definition block_hash
            (DB : Ty.t)
            (ε : list Value.t)
            (τ : list Ty.t)
            (α : list Value.t)
            : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; number ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let number := M.alloc (| number |) in
              M.catch_return (|
                ltac:(M.monadic
                  (M.read (|
                    let~ u64num :=
                      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",
                            [ Ty.path "u64" ]
                          |),
                          [ number ]
                        |)
                      |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply
                              (Ty.path "alloc::collections::btree::map::BTreeMap")
                              []
                              [
                                Ty.path "u64";
                                Ty.apply
                                  (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                                  [ Value.Integer IntegerKind.Usize 32 ]
                                  [];
                                Ty.path "alloc::alloc::Global"
                              ],
                            "entry",
                            []
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "revm::db::states::state::State",
                              "block_hashes"
                            |);
                            M.read (| u64num |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "alloc::collections::btree::map::entry::Entry::Occupied",
                                0
                              |) in
                            let entry := M.copy (| γ0_0 |) in
                            M.alloc (|
                              Value.StructTuple
                                "core::result::Result::Ok"
                                [
                                  M.read (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply
                                          (Ty.path
                                            "alloc::collections::btree::map::entry::OccupiedEntry")
                                          []
                                          [
                                            Ty.path "u64";
                                            Ty.apply
                                              (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                                              [ Value.Integer IntegerKind.Usize 32 ]
                                              [];
                                            Ty.path "alloc::alloc::Global"
                                          ],
                                        "get",
                                        []
                                      |),
                                      [ entry ]
                                    |)
                                  |)
                                ]
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "alloc::collections::btree::map::entry::Entry::Vacant",
                                0
                              |) in
                            let entry := M.copy (| γ0_0 |) in
                            let~ ret :=
                              M.copy (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply
                                      (Ty.path "alloc::collections::btree::map::entry::VacantEntry")
                                      []
                                      [
                                        Ty.path "u64";
                                        Ty.apply
                                          (Ty.path "alloy_primitives::bits::fixed::FixedBytes")
                                          [ Value.Integer IntegerKind.Usize 32 ]
                                          [];
                                        Ty.path "alloc::alloc::Global"
                                      ],
                                    "insert",
                                    []
                                  |),
                                  [
                                    M.read (| entry |);
                                    M.read (|
                                      M.match_operator (|
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::ops::try_trait::Try",
                                              Ty.apply
                                                (Ty.path "core::result::Result")
                                                []
                                                [
                                                  Ty.apply
                                                    (Ty.path
                                                      "alloy_primitives::bits::fixed::FixedBytes")
                                                    [ Value.Integer IntegerKind.Usize 32 ]
                                                    [];
                                                  Ty.associated
                                                ],
                                              [],
                                              "branch",
                                              []
                                            |),
                                            [
                                              M.call_closure (|
                                                M.get_trait_method (|
                                                  "revm_primitives::db::Database",
                                                  DB,
                                                  [],
                                                  "block_hash",
                                                  []
                                                |),
                                                [
                                                  M.SubPointer.get_struct_record_field (|
                                                    M.read (| self |),
                                                    "revm::db::states::state::State",
                                                    "database"
                                                  |);
                                                  M.read (| number |)
                                                ]
                                              |)
                                            ]
                                          |)
                                        |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ0_0 :=
                                                M.SubPointer.get_struct_tuple_field (|
                                                  γ,
                                                  "core::ops::control_flow::ControlFlow::Break",
                                                  0
                                                |) in
                                              let residual := M.copy (| γ0_0 |) in
                                              M.alloc (|
                                                M.never_to_any (|
                                                  M.read (|
                                                    M.return_ (|
                                                      M.call_closure (|
                                                        M.get_trait_method (|
                                                          "core::ops::try_trait::FromResidual",
                                                          Ty.apply
                                                            (Ty.path "core::result::Result")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path
                                                                  "alloy_primitives::bits::fixed::FixedBytes")
                                                                [ Value.Integer IntegerKind.Usize 32
                                                                ]
                                                                [];
                                                              Ty.associated
                                                            ],
                                                          [
                                                            Ty.apply
                                                              (Ty.path "core::result::Result")
                                                              []
                                                              [
                                                                Ty.path "core::convert::Infallible";
                                                                Ty.associated
                                                              ]
                                                          ],
                                                          "from_residual",
                                                          []
                                                        |),
                                                        [ M.read (| residual |) ]
                                                      |)
                                                    |)
                                                  |)
                                                |)
                                              |)));
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ0_0 :=
                                                M.SubPointer.get_struct_tuple_field (|
                                                  γ,
                                                  "core::ops::control_flow::ControlFlow::Continue",
                                                  0
                                                |) in
                                              let val := M.copy (| γ0_0 |) in
                                              val))
                                        ]
                                      |)
                                    |)
                                  ]
                                |)
                              |) in
                            let~ _ :=
                              M.loop (|
                                ltac:(M.monadic
                                  (M.match_operator (|
                                    M.alloc (| Value.Tuple [] |),
                                    [
                                      fun γ =>
                                        ltac:(M.monadic
                                          (let γ :=
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.apply
                                                    (Ty.path
                                                      "alloc::collections::btree::map::BTreeMap")
                                                    []
                                                    [
                                                      Ty.path "u64";
                                                      Ty.apply
                                                        (Ty.path
                                                          "alloy_primitives::bits::fixed::FixedBytes")
                                                        [ Value.Integer IntegerKind.Usize 32 ]
                                                        [];
                                                      Ty.path "alloc::alloc::Global"
                                                    ],
                                                  "first_entry",
                                                  []
                                                |),
                                                [
                                                  M.SubPointer.get_struct_record_field (|
                                                    M.read (| self |),
                                                    "revm::db::states::state::State",
                                                    "block_hashes"
                                                  |)
                                                ]
                                              |)
                                            |) in
                                          let γ0_0 :=
                                            M.SubPointer.get_struct_tuple_field (|
                                              γ,
                                              "core::option::Option::Some",
                                              0
                                            |) in
                                          let entry := M.copy (| γ0_0 |) in
                                          M.match_operator (|
                                            M.alloc (| Value.Tuple [] |),
                                            [
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (let γ :=
                                                    M.use
                                                      (M.alloc (|
                                                        BinOp.lt (|
                                                          M.read (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.apply
                                                                  (Ty.path
                                                                    "alloc::collections::btree::map::entry::OccupiedEntry")
                                                                  []
                                                                  [
                                                                    Ty.path "u64";
                                                                    Ty.apply
                                                                      (Ty.path
                                                                        "alloy_primitives::bits::fixed::FixedBytes")
                                                                      [
                                                                        Value.Integer
                                                                          IntegerKind.Usize
                                                                          32
                                                                      ]
                                                                      [];
                                                                    Ty.path "alloc::alloc::Global"
                                                                  ],
                                                                "key",
                                                                []
                                                              |),
                                                              [ entry ]
                                                            |)
                                                          |),
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path "u64",
                                                              "saturating_sub",
                                                              []
                                                            |),
                                                            [
                                                              M.read (| u64num |);
                                                              M.rust_cast
                                                                (M.read (|
                                                                  M.get_constant (|
                                                                    "revm_primitives::constants::BLOCK_HASH_HISTORY"
                                                                  |)
                                                                |))
                                                            ]
                                                          |)
                                                        |)
                                                      |)) 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
                                                              "alloc::collections::btree::map::entry::OccupiedEntry")
                                                            []
                                                            [
                                                              Ty.path "u64";
                                                              Ty.apply
                                                                (Ty.path
                                                                  "alloy_primitives::bits::fixed::FixedBytes")
                                                                [ Value.Integer IntegerKind.Usize 32
                                                                ]
                                                                [];
                                                              Ty.path "alloc::alloc::Global"
                                                            ],
                                                          "remove",
                                                          []
                                                        |),
                                                        [ M.read (| entry |) ]
                                                      |)
                                                    |) in
                                                  M.alloc (| Value.Tuple [] |)));
                                              fun γ =>
                                                ltac:(M.monadic
                                                  (M.alloc (|
                                                    M.never_to_any (| M.read (| M.break (||) |) |)
                                                  |)))
                                            ]
                                          |)));
                                      fun γ =>
                                        ltac:(M.monadic
                                          (M.alloc (|
                                            M.never_to_any (|
                                              M.read (|
                                                let~ _ :=
                                                  M.alloc (|
                                                    M.never_to_any (| M.read (| M.break (||) |) |)
                                                  |) in
                                                M.alloc (| Value.Tuple [] |)
                                              |)
                                            |)
                                          |)))
                                    ]
                                  |)))
                              |) in
                            M.alloc (|
                              Value.StructTuple "core::result::Result::Ok" [ M.read (| ret |) ]
                            |)))
                      ]
                    |)
                  |)))
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (DB : Ty.t),
          M.IsTraitInstance
            "revm_primitives::db::Database"
            (Self DB)
            (* Trait polymorphic types *) []
            (* Instance *)
            [
              ("Error", InstanceField.Ty (_Error DB));
              ("basic", InstanceField.Method (basic DB));
              ("code_by_hash", InstanceField.Method (code_by_hash DB));
              ("storage", InstanceField.Method (storage DB));
              ("block_hash", InstanceField.Method (block_hash DB))
            ].
      End Impl_revm_primitives_db_Database_where_revm_primitives_db_Database_DB_for_revm_db_states_state_State_DB.
      
      Module Impl_revm_primitives_db_DatabaseCommit_where_revm_primitives_db_Database_DB_for_revm_db_states_state_State_DB.
        Definition Self (DB : Ty.t) : Ty.t :=
          Ty.apply (Ty.path "revm::db::states::state::State") [] [ DB ].
        
        (*
            fn commit(&mut self, evm_state: HashMap<Address, Account>) {
                let transitions = self.cache.apply_evm_state(evm_state);
                self.apply_transition(transitions);
            }
        *)
        Definition commit (DB : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
          let Self : Ty.t := Self DB in
          match ε, τ, α with
          | [], [], [ self; evm_state ] =>
            ltac:(M.monadic
              (let self := M.alloc (| self |) in
              let evm_state := M.alloc (| evm_state |) in
              M.read (|
                let~ transitions :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm::db::states::cache::CacheState",
                        "apply_evm_state",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "revm::db::states::state::State",
                          "cache"
                        |);
                        M.read (| evm_state |)
                      ]
                    |)
                  |) in
                let~ _ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "revm::db::states::state::State") [] [ DB ],
                        "apply_transition",
                        []
                      |),
                      [ M.read (| self |); M.read (| transitions |) ]
                    |)
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          | _, _, _ => M.impossible "wrong number of arguments"
          end.
        
        Axiom Implements :
          forall (DB : Ty.t),
          M.IsTraitInstance
            "revm_primitives::db::DatabaseCommit"
            (Self DB)
            (* Trait polymorphic types *) []
            (* Instance *) [ ("commit", InstanceField.Method (commit DB)) ].
      End Impl_revm_primitives_db_DatabaseCommit_where_revm_primitives_db_Database_DB_for_revm_db_states_state_State_DB.
    End state.
  End states.
End db.
