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

Module instructions.
  Module control.
    (*
    pub fn rjump<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        require_eof!(interpreter);
        gas!(interpreter, gas::BASE);
        let offset = unsafe { read_i16(interpreter.instruction_pointer) } as isize;
        // In spec it is +3 but pointer is already incremented in
        // `Interpreter::step` so for revm is +2.
        interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset + 2) };
    }
    *)
    Definition rjump (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "is_eof"
                                    |)
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::EOFOpcodeDisabledInLegacy"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (|
                                          "revm_interpreter::gas::constants::BASE"
                                        |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ offset :=
                  M.alloc (|
                    M.rust_cast
                      (M.call_closure (|
                        M.get_function (|
                          "revm_interpreter::instructions::utility::read_i16",
                          []
                        |),
                        [
                          M.read (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| interpreter |),
                              "revm_interpreter::interpreter::Interpreter",
                              "instruction_pointer"
                            |)
                          |)
                        ]
                      |))
                  |) in
                let~ _ :=
                  M.write (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| interpreter |),
                      "revm_interpreter::interpreter::Interpreter",
                      "instruction_pointer"
                    |),
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "*const") [] [ Ty.path "u8" ],
                        "offset",
                        []
                      |),
                      [
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| interpreter |),
                            "revm_interpreter::interpreter::Interpreter",
                            "instruction_pointer"
                          |)
                        |);
                        BinOp.Wrap.add (| M.read (| offset |), Value.Integer IntegerKind.Isize 2 |)
                      ]
                    |)
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_rjump : M.IsFunction "revm_interpreter::instructions::control::rjump" rjump.
    
    (*
    pub fn rjumpi<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        require_eof!(interpreter);
        gas!(interpreter, gas::CONDITION_JUMP_GAS);
        pop!(interpreter, condition);
        // In spec it is +3 but pointer is already incremented in
        // `Interpreter::step` so for revm is +2.
        let mut offset = 2;
        if !condition.is_zero() {
            offset += unsafe { read_i16(interpreter.instruction_pointer) } as isize;
        }
    
        interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) };
    }
    *)
    Definition rjumpi (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "is_eof"
                                    |)
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::EOFOpcodeDisabledInLegacy"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (|
                                          "revm_interpreter::gas::constants::CONDITION_JUMP_GAS"
                                        |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::interpreter::stack::Stack",
                                      "len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "stack"
                                      |)
                                    ]
                                  |),
                                  Value.Integer IntegerKind.Usize 1
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::StackUnderflow"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ condition :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm_interpreter::interpreter::stack::Stack",
                        "pop_unsafe",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| interpreter |),
                          "revm_interpreter::interpreter::Interpreter",
                          "stack"
                        |)
                      ]
                    |)
                  |) in
                let~ offset := M.alloc (| Value.Integer IntegerKind.Isize 2 |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "ruint::Uint")
                                        [
                                          Value.Integer IntegerKind.Usize 256;
                                          Value.Integer IntegerKind.Usize 4
                                        ]
                                        [],
                                      "is_zero",
                                      []
                                    |),
                                    [ condition ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            let β := offset in
                            M.write (|
                              β,
                              BinOp.Wrap.add (|
                                M.read (| β |),
                                M.rust_cast
                                  (M.call_closure (|
                                    M.get_function (|
                                      "revm_interpreter::instructions::utility::read_i16",
                                      []
                                    |),
                                    [
                                      M.read (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| interpreter |),
                                          "revm_interpreter::interpreter::Interpreter",
                                          "instruction_pointer"
                                        |)
                                      |)
                                    ]
                                  |))
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.write (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| interpreter |),
                      "revm_interpreter::interpreter::Interpreter",
                      "instruction_pointer"
                    |),
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "*const") [] [ Ty.path "u8" ],
                        "offset",
                        []
                      |),
                      [
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| interpreter |),
                            "revm_interpreter::interpreter::Interpreter",
                            "instruction_pointer"
                          |)
                        |);
                        M.read (| offset |)
                      ]
                    |)
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_rjumpi : M.IsFunction "revm_interpreter::instructions::control::rjumpi" rjumpi.
    
    (*
    pub fn rjumpv<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        require_eof!(interpreter);
        gas!(interpreter, gas::CONDITION_JUMP_GAS);
        pop!(interpreter, case);
        let case = as_isize_saturated!(case);
    
        let max_index = unsafe { *interpreter.instruction_pointer } as isize;
        // for number of items we are adding 1 to max_index, multiply by 2 as each offset is 2 bytes
        // and add 1 for max_index itself. Note that revm already incremented the instruction pointer
        let mut offset = (max_index + 1) * 2 + 1;
    
        if case <= max_index {
            offset += unsafe {
                read_i16(
                    interpreter
                        .instruction_pointer
                        // offset for max_index that is one byte
                        .offset(1 + case * 2),
                )
            } as isize;
        }
    
        interpreter.instruction_pointer = unsafe { interpreter.instruction_pointer.offset(offset) };
    }
    *)
    Definition rjumpv (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "is_eof"
                                    |)
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::EOFOpcodeDisabledInLegacy"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (|
                                          "revm_interpreter::gas::constants::CONDITION_JUMP_GAS"
                                        |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::interpreter::stack::Stack",
                                      "len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "stack"
                                      |)
                                    ]
                                  |),
                                  Value.Integer IntegerKind.Usize 1
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::StackUnderflow"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ case :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm_interpreter::interpreter::stack::Stack",
                        "pop_unsafe",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| interpreter |),
                          "revm_interpreter::interpreter::Interpreter",
                          "stack"
                        |)
                      ]
                    |)
                  |) in
                let~ case :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply
                          (Ty.path "core::result::Result")
                          []
                          [ Ty.path "isize"; Ty.path "core::num::error::TryFromIntError" ],
                        "unwrap_or",
                        []
                      |),
                      [
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::convert::TryFrom",
                            Ty.path "isize",
                            [ Ty.path "u64" ],
                            "try_from",
                            []
                          |),
                          [
                            M.read (|
                              let~ x :=
                                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
                                        ]
                                        [],
                                      "as_limbs",
                                      []
                                    |),
                                    [ case ]
                                  |)
                                |) in
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            LogicalOp.and (|
                                              LogicalOp.and (|
                                                BinOp.eq (|
                                                  M.read (|
                                                    M.SubPointer.get_array_field (|
                                                      M.read (| x |),
                                                      M.alloc (|
                                                        Value.Integer IntegerKind.Usize 1
                                                      |)
                                                    |)
                                                  |),
                                                  Value.Integer IntegerKind.U64 0
                                                |),
                                                ltac:(M.monadic
                                                  (BinOp.eq (|
                                                    M.read (|
                                                      M.SubPointer.get_array_field (|
                                                        M.read (| x |),
                                                        M.alloc (|
                                                          Value.Integer IntegerKind.Usize 2
                                                        |)
                                                      |)
                                                    |),
                                                    Value.Integer IntegerKind.U64 0
                                                  |)))
                                              |),
                                              ltac:(M.monadic
                                                (BinOp.eq (|
                                                  M.read (|
                                                    M.SubPointer.get_array_field (|
                                                      M.read (| x |),
                                                      M.alloc (|
                                                        Value.Integer IntegerKind.Usize 3
                                                      |)
                                                    |)
                                                  |),
                                                  Value.Integer IntegerKind.U64 0
                                                |)))
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.SubPointer.get_array_field (|
                                        M.read (| x |),
                                        M.alloc (| Value.Integer IntegerKind.Usize 0 |)
                                      |)));
                                  fun γ => ltac:(M.monadic (M.get_constant (| "core::num::MAX" |)))
                                ]
                              |)
                            |)
                          ]
                        |);
                        M.read (| M.get_constant (| "core::num::MAX" |) |)
                      ]
                    |)
                  |) in
                let~ max_index :=
                  M.alloc (|
                    M.rust_cast
                      (M.read (|
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| interpreter |),
                            "revm_interpreter::interpreter::Interpreter",
                            "instruction_pointer"
                          |)
                        |)
                      |))
                  |) in
                let~ offset :=
                  M.alloc (|
                    BinOp.Wrap.add (|
                      BinOp.Wrap.mul (|
                        BinOp.Wrap.add (|
                          M.read (| max_index |),
                          Value.Integer IntegerKind.Isize 1
                        |),
                        Value.Integer IntegerKind.Isize 2
                      |),
                      Value.Integer IntegerKind.Isize 1
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.le (| M.read (| case |), M.read (| max_index |) |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          let~ _ :=
                            let β := offset in
                            M.write (|
                              β,
                              BinOp.Wrap.add (|
                                M.read (| β |),
                                M.rust_cast
                                  (M.call_closure (|
                                    M.get_function (|
                                      "revm_interpreter::instructions::utility::read_i16",
                                      []
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply (Ty.path "*const") [] [ Ty.path "u8" ],
                                          "offset",
                                          []
                                        |),
                                        [
                                          M.read (|
                                            M.SubPointer.get_struct_record_field (|
                                              M.read (| interpreter |),
                                              "revm_interpreter::interpreter::Interpreter",
                                              "instruction_pointer"
                                            |)
                                          |);
                                          BinOp.Wrap.add (|
                                            Value.Integer IntegerKind.Isize 1,
                                            BinOp.Wrap.mul (|
                                              M.read (| case |),
                                              Value.Integer IntegerKind.Isize 2
                                            |)
                                          |)
                                        ]
                                      |)
                                    ]
                                  |))
                              |)
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.write (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| interpreter |),
                      "revm_interpreter::interpreter::Interpreter",
                      "instruction_pointer"
                    |),
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "*const") [] [ Ty.path "u8" ],
                        "offset",
                        []
                      |),
                      [
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| interpreter |),
                            "revm_interpreter::interpreter::Interpreter",
                            "instruction_pointer"
                          |)
                        |);
                        M.read (| offset |)
                      ]
                    |)
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_rjumpv : M.IsFunction "revm_interpreter::instructions::control::rjumpv" rjumpv.
    
    (*
    pub fn jump<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        gas!(interpreter, gas::MID);
        pop!(interpreter, target);
        jump_inner(interpreter, target);
    }
    *)
    Definition jump (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (| "revm_interpreter::gas::constants::MID" |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::interpreter::stack::Stack",
                                      "len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "stack"
                                      |)
                                    ]
                                  |),
                                  Value.Integer IntegerKind.Usize 1
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::StackUnderflow"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ target :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm_interpreter::interpreter::stack::Stack",
                        "pop_unsafe",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| interpreter |),
                          "revm_interpreter::interpreter::Interpreter",
                          "stack"
                        |)
                      ]
                    |)
                  |) in
                let~ _ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (|
                        "revm_interpreter::instructions::control::jump_inner",
                        []
                      |),
                      [ M.read (| interpreter |); M.read (| target |) ]
                    |)
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_jump : M.IsFunction "revm_interpreter::instructions::control::jump" jump.
    
    (*
    pub fn jumpi<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        gas!(interpreter, gas::HIGH);
        pop!(interpreter, target, cond);
        if cond != U256::ZERO {
            jump_inner(interpreter, target);
        }
    }
    *)
    Definition jumpi (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (|
                                          "revm_interpreter::gas::constants::HIGH"
                                        |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::interpreter::stack::Stack",
                                      "len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "stack"
                                      |)
                                    ]
                                  |),
                                  Value.Integer IntegerKind.Usize 2
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::StackUnderflow"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                M.match_operator (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm_interpreter::interpreter::stack::Stack",
                        "pop2_unsafe",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| interpreter |),
                          "revm_interpreter::interpreter::Interpreter",
                          "stack"
                        |)
                      ]
                    |)
                  |),
                  [
                    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 target := M.copy (| γ0_0 |) in
                        let cond := M.copy (| γ0_1 |) in
                        M.match_operator (|
                          M.alloc (| Value.Tuple [] |),
                          [
                            fun γ =>
                              ltac:(M.monadic
                                (let γ :=
                                  M.use
                                    (M.alloc (|
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::cmp::PartialEq",
                                          Ty.apply
                                            (Ty.path "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
                                              ]
                                              []
                                          ],
                                          "ne",
                                          []
                                        |),
                                        [ cond; M.get_constant (| "ruint::ZERO" |) ]
                                      |)
                                    |)) in
                                let _ :=
                                  M.is_constant_or_break_match (|
                                    M.read (| γ |),
                                    Value.Bool true
                                  |) in
                                let~ _ :=
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "revm_interpreter::instructions::control::jump_inner",
                                        []
                                      |),
                                      [ M.read (| interpreter |); M.read (| target |) ]
                                    |)
                                  |) in
                                M.alloc (| Value.Tuple [] |)));
                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                          ]
                        |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_jumpi : M.IsFunction "revm_interpreter::instructions::control::jumpi" jumpi.
    
    (*
    fn jump_inner(interpreter: &mut Interpreter, target: U256) {
        let target = as_usize_or_fail!(interpreter, target, InstructionResult::InvalidJump);
        if !interpreter.contract.is_valid_jump(target) {
            interpreter.instruction_result = InstructionResult::InvalidJump;
            return;
        }
        // SAFETY: `is_valid_jump` ensures that `dest` is in bounds.
        interpreter.instruction_pointer = unsafe { interpreter.bytecode.as_ptr().add(target) };
    }
    *)
    Definition jump_inner (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ interpreter; target ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let target := M.alloc (| target |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ target :=
                  M.copy (|
                    let~ x :=
                      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
                              ]
                              [],
                            "as_limbs",
                            []
                          |),
                          [ target ]
                        |)
                      |) in
                    let~ _ :=
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    LogicalOp.or (|
                                      LogicalOp.or (|
                                        BinOp.ne (|
                                          M.read (|
                                            M.SubPointer.get_array_field (|
                                              M.read (| x |),
                                              M.alloc (| Value.Integer IntegerKind.Usize 1 |)
                                            |)
                                          |),
                                          Value.Integer IntegerKind.U64 0
                                        |),
                                        ltac:(M.monadic
                                          (BinOp.ne (|
                                            M.read (|
                                              M.SubPointer.get_array_field (|
                                                M.read (| x |),
                                                M.alloc (| Value.Integer IntegerKind.Usize 2 |)
                                              |)
                                            |),
                                            Value.Integer IntegerKind.U64 0
                                          |)))
                                      |),
                                      ltac:(M.monadic
                                        (BinOp.ne (|
                                          M.read (|
                                            M.SubPointer.get_array_field (|
                                              M.read (| x |),
                                              M.alloc (| Value.Integer IntegerKind.Usize 3 |)
                                            |)
                                          |),
                                          Value.Integer IntegerKind.U64 0
                                        |)))
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    let~ _ :=
                                      M.write (|
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| interpreter |),
                                          "revm_interpreter::interpreter::Interpreter",
                                          "instruction_result"
                                        |),
                                        Value.StructTuple
                                          "revm_interpreter::instruction_result::InstructionResult::InvalidJump"
                                          []
                                      |) in
                                    M.return_ (| Value.Tuple [] |)
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |) in
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::convert::TryFrom",
                            Ty.path "usize",
                            [ Ty.path "u64" ],
                            "try_from",
                            []
                          |),
                          [
                            M.read (|
                              M.SubPointer.get_array_field (|
                                M.read (| x |),
                                M.alloc (| Value.Integer IntegerKind.Usize 0 |)
                              |)
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::result::Result::Ok",
                                0
                              |) in
                            let val := M.copy (| γ0_0 |) in
                            val))
                      ]
                    |)
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::interpreter::contract::Contract",
                                      "is_valid_jump",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "contract"
                                      |);
                                      M.read (| target |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::InvalidJump"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.write (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| interpreter |),
                      "revm_interpreter::interpreter::Interpreter",
                      "instruction_pointer"
                    |),
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply (Ty.path "*const") [] [ Ty.path "u8" ],
                        "add",
                        []
                      |),
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                            "as_ptr",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::ops::deref::Deref",
                                Ty.path "bytes::bytes::Bytes",
                                [],
                                "deref",
                                []
                              |),
                              [
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::ops::deref::Deref",
                                    Ty.path "alloy_primitives::bytes_::Bytes",
                                    [],
                                    "deref",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "bytecode"
                                    |)
                                  ]
                                |)
                              ]
                            |)
                          ]
                        |);
                        M.read (| target |)
                      ]
                    |)
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_jump_inner :
      M.IsFunction "revm_interpreter::instructions::control::jump_inner" jump_inner.
    
    (*
    pub fn jumpdest_or_nop<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        gas!(interpreter, gas::JUMPDEST);
    }
    *)
    Definition jumpdest_or_nop (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (|
                                          "revm_interpreter::gas::constants::JUMPDEST"
                                        |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_jumpdest_or_nop :
      M.IsFunction "revm_interpreter::instructions::control::jumpdest_or_nop" jumpdest_or_nop.
    
    (*
    pub fn callf<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        require_eof!(interpreter);
        gas!(interpreter, gas::LOW);
    
        let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize;
        // TODO Check stack with EOF types.
    
        if interpreter.function_stack.return_stack_len() == 1024 {
            interpreter.instruction_result = InstructionResult::EOFFunctionStackOverflow;
            return;
        }
    
        // push current idx and PC to the callf stack.
        // PC is incremented by 2 to point to the next instruction after callf.
        interpreter
            .function_stack
            .push(interpreter.program_counter() + 2, idx);
    
        interpreter.load_eof_code(idx, 0)
    }
    *)
    Definition callf (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "is_eof"
                                    |)
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::EOFOpcodeDisabledInLegacy"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (| "revm_interpreter::gas::constants::LOW" |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ idx :=
                  M.alloc (|
                    M.rust_cast
                      (M.call_closure (|
                        M.get_function (|
                          "revm_interpreter::instructions::utility::read_u16",
                          []
                        |),
                        [
                          M.read (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| interpreter |),
                              "revm_interpreter::interpreter::Interpreter",
                              "instruction_pointer"
                            |)
                          |)
                        ]
                      |))
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::function_stack::FunctionStack",
                                      "return_stack_len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "function_stack"
                                      |)
                                    ]
                                  |),
                                  Value.Integer IntegerKind.Usize 1024
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::EOFFunctionStackOverflow"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm_interpreter::function_stack::FunctionStack",
                        "push",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| interpreter |),
                          "revm_interpreter::interpreter::Interpreter",
                          "function_stack"
                        |);
                        BinOp.Wrap.add (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path "revm_interpreter::interpreter::Interpreter",
                              "program_counter",
                              []
                            |),
                            [ M.read (| interpreter |) ]
                          |),
                          Value.Integer IntegerKind.Usize 2
                        |);
                        M.read (| idx |)
                      ]
                    |)
                  |) in
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "revm_interpreter::interpreter::Interpreter",
                      "load_eof_code",
                      []
                    |),
                    [ M.read (| interpreter |); M.read (| idx |); Value.Integer IntegerKind.Usize 0
                    ]
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_callf : M.IsFunction "revm_interpreter::instructions::control::callf" callf.
    
    (*
    pub fn retf<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        require_eof!(interpreter);
        gas!(interpreter, gas::RETF_GAS);
    
        let Some(fframe) = interpreter.function_stack.pop() else {
            panic!("Expected function frame")
        };
    
        interpreter.load_eof_code(fframe.idx, fframe.pc);
    }
    *)
    Definition retf (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "is_eof"
                                    |)
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::EOFOpcodeDisabledInLegacy"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (|
                                          "revm_interpreter::gas::constants::RETF_GAS"
                                        |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                M.match_operator (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm_interpreter::function_stack::FunctionStack",
                        "pop",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| interpreter |),
                          "revm_interpreter::interpreter::Interpreter",
                          "function_stack"
                        |)
                      ]
                    |)
                  |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ0_0 :=
                          M.SubPointer.get_struct_tuple_field (|
                            γ,
                            "core::option::Option::Some",
                            0
                          |) in
                        let fframe := M.copy (| γ0_0 |) in
                        let~ _ :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "revm_interpreter::interpreter::Interpreter",
                                "load_eof_code",
                                []
                              |),
                              [
                                M.read (| interpreter |);
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    fframe,
                                    "revm_interpreter::function_stack::FunctionReturnFrame",
                                    "idx"
                                  |)
                                |);
                                M.read (|
                                  M.SubPointer.get_struct_record_field (|
                                    fframe,
                                    "revm_interpreter::function_stack::FunctionReturnFrame",
                                    "pc"
                                  |)
                                |)
                              ]
                            |)
                          |) in
                        M.alloc (| Value.Tuple [] |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_retf : M.IsFunction "revm_interpreter::instructions::control::retf" retf.
    
    (*
    pub fn jumpf<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        require_eof!(interpreter);
        gas!(interpreter, gas::LOW);
    
        let idx = unsafe { read_u16(interpreter.instruction_pointer) } as usize;
    
        // TODO(EOF) do types stack checks
    
        interpreter.function_stack.set_current_code_idx(idx);
        interpreter.load_eof_code(idx, 0)
    }
    *)
    Definition jumpf (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "is_eof"
                                    |)
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::EOFOpcodeDisabledInLegacy"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (| "revm_interpreter::gas::constants::LOW" |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ idx :=
                  M.alloc (|
                    M.rust_cast
                      (M.call_closure (|
                        M.get_function (|
                          "revm_interpreter::instructions::utility::read_u16",
                          []
                        |),
                        [
                          M.read (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| interpreter |),
                              "revm_interpreter::interpreter::Interpreter",
                              "instruction_pointer"
                            |)
                          |)
                        ]
                      |))
                  |) in
                let~ _ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm_interpreter::function_stack::FunctionStack",
                        "set_current_code_idx",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| interpreter |),
                          "revm_interpreter::interpreter::Interpreter",
                          "function_stack"
                        |);
                        M.read (| idx |)
                      ]
                    |)
                  |) in
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "revm_interpreter::interpreter::Interpreter",
                      "load_eof_code",
                      []
                    |),
                    [ M.read (| interpreter |); M.read (| idx |); Value.Integer IntegerKind.Usize 0
                    ]
                  |)
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_jumpf : M.IsFunction "revm_interpreter::instructions::control::jumpf" jumpf.
    
    (*
    pub fn pc<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        gas!(interpreter, gas::BASE);
        // - 1 because we have already advanced the instruction pointer in `Interpreter::step`
        push!(interpreter, U256::from(interpreter.program_counter() - 1));
    }
    *)
    Definition pc (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::gas::Gas",
                                      "record_cost",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "gas"
                                      |);
                                      M.read (|
                                        M.get_constant (|
                                          "revm_interpreter::gas::constants::BASE"
                                        |)
                                      |)
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::OutOfGas"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path "revm_interpreter::interpreter::stack::Stack",
                          "push",
                          []
                        |),
                        [
                          M.SubPointer.get_struct_record_field (|
                            M.read (| interpreter |),
                            "revm_interpreter::interpreter::Interpreter",
                            "stack"
                          |);
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "ruint::Uint")
                                [
                                  Value.Integer IntegerKind.Usize 256;
                                  Value.Integer IntegerKind.Usize 4
                                ]
                                [],
                              "from",
                              [ Ty.path "usize" ]
                            |),
                            [
                              BinOp.Wrap.sub (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "revm_interpreter::interpreter::Interpreter",
                                    "program_counter",
                                    []
                                  |),
                                  [ M.read (| interpreter |) ]
                                |),
                                Value.Integer IntegerKind.Usize 1
                              |)
                            ]
                          |)
                        ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::result::Result::Ok",
                              0
                            |) in
                          M.alloc (| Value.Tuple [] |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "core::result::Result::Err",
                              0
                            |) in
                          let e := M.copy (| γ0_0 |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    M.read (| e |)
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)))
                    ]
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_pc : M.IsFunction "revm_interpreter::instructions::control::pc" pc.
    
    (*
    fn return_inner(interpreter: &mut Interpreter, instruction_result: InstructionResult) {
        // zero gas cost
        // gas!(interpreter, gas::ZERO);
        pop!(interpreter, offset, len);
        let len = as_usize_or_fail!(interpreter, len);
        // important: offset must be ignored if len is zeros
        let mut output = Bytes::default();
        if len != 0 {
            let offset = as_usize_or_fail!(interpreter, offset);
            resize_memory!(interpreter, offset, len);
    
            output = interpreter.shared_memory.slice(offset, len).to_vec().into()
        }
        interpreter.instruction_result = instruction_result;
        interpreter.next_action = crate::InterpreterAction::Return {
            result: InterpreterResult {
                output,
                gas: interpreter.gas,
                result: instruction_result,
            },
        };
    }
    *)
    Definition return_inner (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [], [ interpreter; instruction_result ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let instruction_result := M.alloc (| instruction_result |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.lt (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "revm_interpreter::interpreter::stack::Stack",
                                      "len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| interpreter |),
                                        "revm_interpreter::interpreter::Interpreter",
                                        "stack"
                                      |)
                                    ]
                                  |),
                                  Value.Integer IntegerKind.Usize 2
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::StackUnderflow"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                M.match_operator (|
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "revm_interpreter::interpreter::stack::Stack",
                        "pop2_unsafe",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| interpreter |),
                          "revm_interpreter::interpreter::Interpreter",
                          "stack"
                        |)
                      ]
                    |)
                  |),
                  [
                    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 offset := M.copy (| γ0_0 |) in
                        let len := M.copy (| γ0_1 |) in
                        let~ len :=
                          M.copy (|
                            let~ x :=
                              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
                                      ]
                                      [],
                                    "as_limbs",
                                    []
                                  |),
                                  [ len ]
                                |)
                              |) in
                            let~ _ :=
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ :=
                                        M.use
                                          (M.alloc (|
                                            LogicalOp.or (|
                                              LogicalOp.or (|
                                                BinOp.ne (|
                                                  M.read (|
                                                    M.SubPointer.get_array_field (|
                                                      M.read (| x |),
                                                      M.alloc (|
                                                        Value.Integer IntegerKind.Usize 1
                                                      |)
                                                    |)
                                                  |),
                                                  Value.Integer IntegerKind.U64 0
                                                |),
                                                ltac:(M.monadic
                                                  (BinOp.ne (|
                                                    M.read (|
                                                      M.SubPointer.get_array_field (|
                                                        M.read (| x |),
                                                        M.alloc (|
                                                          Value.Integer IntegerKind.Usize 2
                                                        |)
                                                      |)
                                                    |),
                                                    Value.Integer IntegerKind.U64 0
                                                  |)))
                                              |),
                                              ltac:(M.monadic
                                                (BinOp.ne (|
                                                  M.read (|
                                                    M.SubPointer.get_array_field (|
                                                      M.read (| x |),
                                                      M.alloc (|
                                                        Value.Integer IntegerKind.Usize 3
                                                      |)
                                                    |)
                                                  |),
                                                  Value.Integer IntegerKind.U64 0
                                                |)))
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            let~ _ :=
                                              M.write (|
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| interpreter |),
                                                  "revm_interpreter::interpreter::Interpreter",
                                                  "instruction_result"
                                                |),
                                                Value.StructTuple
                                                  "revm_interpreter::instruction_result::InstructionResult::InvalidOperandOOG"
                                                  []
                                              |) in
                                            M.return_ (| Value.Tuple [] |)
                                          |)
                                        |)
                                      |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::convert::TryFrom",
                                    Ty.path "usize",
                                    [ Ty.path "u64" ],
                                    "try_from",
                                    []
                                  |),
                                  [
                                    M.read (|
                                      M.SubPointer.get_array_field (|
                                        M.read (| x |),
                                        M.alloc (| Value.Integer IntegerKind.Usize 0 |)
                                      |)
                                    |)
                                  ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::result::Result::Ok",
                                        0
                                      |) in
                                    let val := M.copy (| γ0_0 |) in
                                    val))
                              ]
                            |)
                          |) in
                        let~ output :=
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::default::Default",
                                Ty.path "alloy_primitives::bytes_::Bytes",
                                [],
                                "default",
                                []
                              |),
                              []
                            |)
                          |) in
                        let~ _ :=
                          M.match_operator (|
                            M.alloc (| Value.Tuple [] |),
                            [
                              fun γ =>
                                ltac:(M.monadic
                                  (let γ :=
                                    M.use
                                      (M.alloc (|
                                        BinOp.ne (|
                                          M.read (| len |),
                                          Value.Integer IntegerKind.Usize 0
                                        |)
                                      |)) in
                                  let _ :=
                                    M.is_constant_or_break_match (|
                                      M.read (| γ |),
                                      Value.Bool true
                                    |) in
                                  let~ offset :=
                                    M.copy (|
                                      let~ x :=
                                        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
                                                ]
                                                [],
                                              "as_limbs",
                                              []
                                            |),
                                            [ offset ]
                                          |)
                                        |) in
                                      let~ _ :=
                                        M.match_operator (|
                                          M.alloc (| Value.Tuple [] |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ :=
                                                  M.use
                                                    (M.alloc (|
                                                      LogicalOp.or (|
                                                        LogicalOp.or (|
                                                          BinOp.ne (|
                                                            M.read (|
                                                              M.SubPointer.get_array_field (|
                                                                M.read (| x |),
                                                                M.alloc (|
                                                                  Value.Integer IntegerKind.Usize 1
                                                                |)
                                                              |)
                                                            |),
                                                            Value.Integer IntegerKind.U64 0
                                                          |),
                                                          ltac:(M.monadic
                                                            (BinOp.ne (|
                                                              M.read (|
                                                                M.SubPointer.get_array_field (|
                                                                  M.read (| x |),
                                                                  M.alloc (|
                                                                    Value.Integer
                                                                      IntegerKind.Usize
                                                                      2
                                                                  |)
                                                                |)
                                                              |),
                                                              Value.Integer IntegerKind.U64 0
                                                            |)))
                                                        |),
                                                        ltac:(M.monadic
                                                          (BinOp.ne (|
                                                            M.read (|
                                                              M.SubPointer.get_array_field (|
                                                                M.read (| x |),
                                                                M.alloc (|
                                                                  Value.Integer IntegerKind.Usize 3
                                                                |)
                                                              |)
                                                            |),
                                                            Value.Integer IntegerKind.U64 0
                                                          |)))
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                M.alloc (|
                                                  M.never_to_any (|
                                                    M.read (|
                                                      let~ _ :=
                                                        M.write (|
                                                          M.SubPointer.get_struct_record_field (|
                                                            M.read (| interpreter |),
                                                            "revm_interpreter::interpreter::Interpreter",
                                                            "instruction_result"
                                                          |),
                                                          Value.StructTuple
                                                            "revm_interpreter::instruction_result::InstructionResult::InvalidOperandOOG"
                                                            []
                                                        |) in
                                                      M.return_ (| Value.Tuple [] |)
                                                    |)
                                                  |)
                                                |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |) in
                                      M.match_operator (|
                                        M.alloc (|
                                          M.call_closure (|
                                            M.get_trait_method (|
                                              "core::convert::TryFrom",
                                              Ty.path "usize",
                                              [ Ty.path "u64" ],
                                              "try_from",
                                              []
                                            |),
                                            [
                                              M.read (|
                                                M.SubPointer.get_array_field (|
                                                  M.read (| x |),
                                                  M.alloc (| Value.Integer IntegerKind.Usize 0 |)
                                                |)
                                              |)
                                            ]
                                          |)
                                        |),
                                        [
                                          fun γ =>
                                            ltac:(M.monadic
                                              (let γ0_0 :=
                                                M.SubPointer.get_struct_tuple_field (|
                                                  γ,
                                                  "core::result::Result::Ok",
                                                  0
                                                |) in
                                              let val := M.copy (| γ0_0 |) in
                                              val))
                                        ]
                                      |)
                                    |) in
                                  let~ new_size :=
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "usize",
                                          "saturating_add",
                                          []
                                        |),
                                        [ M.read (| offset |); M.read (| len |) ]
                                      |)
                                    |) in
                                  let~ _ :=
                                    M.match_operator (|
                                      M.alloc (| Value.Tuple [] |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ :=
                                              M.use
                                                (M.alloc (|
                                                  BinOp.gt (|
                                                    M.read (| new_size |),
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "revm_interpreter::interpreter::shared_memory::SharedMemory",
                                                        "len",
                                                        []
                                                      |),
                                                      [
                                                        M.SubPointer.get_struct_record_field (|
                                                          M.read (| interpreter |),
                                                          "revm_interpreter::interpreter::Interpreter",
                                                          "shared_memory"
                                                        |)
                                                      ]
                                                    |)
                                                  |)
                                                |)) in
                                            let _ :=
                                              M.is_constant_or_break_match (|
                                                M.read (| γ |),
                                                Value.Bool true
                                              |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          UnOp.not (|
                                                            M.call_closure (|
                                                              M.get_function (|
                                                                "revm_interpreter::interpreter::resize_memory",
                                                                []
                                                              |),
                                                              [
                                                                M.SubPointer.get_struct_record_field (|
                                                                  M.read (| interpreter |),
                                                                  "revm_interpreter::interpreter::Interpreter",
                                                                  "shared_memory"
                                                                |);
                                                                M.SubPointer.get_struct_record_field (|
                                                                  M.read (| interpreter |),
                                                                  "revm_interpreter::interpreter::Interpreter",
                                                                  "gas"
                                                                |);
                                                                M.read (| new_size |)
                                                              ]
                                                            |)
                                                          |)
                                                        |)) in
                                                    let _ :=
                                                      M.is_constant_or_break_match (|
                                                        M.read (| γ |),
                                                        Value.Bool true
                                                      |) in
                                                    M.alloc (|
                                                      M.never_to_any (|
                                                        M.read (|
                                                          let~ _ :=
                                                            M.write (|
                                                              M.SubPointer.get_struct_record_field (|
                                                                M.read (| interpreter |),
                                                                "revm_interpreter::interpreter::Interpreter",
                                                                "instruction_result"
                                                              |),
                                                              Value.StructTuple
                                                                "revm_interpreter::instruction_result::InstructionResult::MemoryOOG"
                                                                []
                                                            |) in
                                                          M.return_ (| Value.Tuple [] |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)));
                                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  M.write (|
                                    output,
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::convert::Into",
                                        Ty.apply
                                          (Ty.path "alloc::vec::Vec")
                                          []
                                          [ Ty.path "u8"; Ty.path "alloc::alloc::Global" ],
                                        [ Ty.path "alloy_primitives::bytes_::Bytes" ],
                                        "into",
                                        []
                                      |),
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.apply (Ty.path "slice") [] [ Ty.path "u8" ],
                                            "to_vec",
                                            []
                                          |),
                                          [
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path
                                                  "revm_interpreter::interpreter::shared_memory::SharedMemory",
                                                "slice",
                                                []
                                              |),
                                              [
                                                M.SubPointer.get_struct_record_field (|
                                                  M.read (| interpreter |),
                                                  "revm_interpreter::interpreter::Interpreter",
                                                  "shared_memory"
                                                |);
                                                M.read (| offset |);
                                                M.read (| len |)
                                              ]
                                            |)
                                          ]
                                        |)
                                      ]
                                    |)
                                  |)));
                              fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                            ]
                          |) in
                        let~ _ :=
                          M.write (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| interpreter |),
                              "revm_interpreter::interpreter::Interpreter",
                              "instruction_result"
                            |),
                            M.read (| instruction_result |)
                          |) in
                        let~ _ :=
                          M.write (|
                            M.SubPointer.get_struct_record_field (|
                              M.read (| interpreter |),
                              "revm_interpreter::interpreter::Interpreter",
                              "next_action"
                            |),
                            Value.StructRecord
                              "revm_interpreter::interpreter_action::InterpreterAction::Return"
                              [
                                ("result",
                                  Value.StructRecord
                                    "revm_interpreter::interpreter::InterpreterResult"
                                    [
                                      ("output", M.read (| output |));
                                      ("gas",
                                        M.read (|
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| interpreter |),
                                            "revm_interpreter::interpreter::Interpreter",
                                            "gas"
                                          |)
                                        |));
                                      ("result", M.read (| instruction_result |))
                                    ])
                              ]
                          |) in
                        M.alloc (| Value.Tuple [] |)))
                  ]
                |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_return_inner :
      M.IsFunction "revm_interpreter::instructions::control::return_inner" return_inner.
    
    (*
    pub fn ret<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        return_inner(interpreter, InstructionResult::Return);
    }
    *)
    Definition ret (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.read (|
            let~ _ :=
              M.alloc (|
                M.call_closure (|
                  M.get_function (| "revm_interpreter::instructions::control::return_inner", [] |),
                  [
                    M.read (| interpreter |);
                    Value.StructTuple
                      "revm_interpreter::instruction_result::InstructionResult::Return"
                      []
                  ]
                |)
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_ret : M.IsFunction "revm_interpreter::instructions::control::ret" ret.
    
    (*
    pub fn revert<H: Host + ?Sized, SPEC: Spec>(interpreter: &mut Interpreter, _host: &mut H) {
        check!(interpreter, BYZANTIUM);
        return_inner(interpreter, InstructionResult::Revert);
    }
    *)
    Definition revert (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H; SPEC ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.catch_return (|
            ltac:(M.monadic
              (M.read (|
                let~ _ :=
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                UnOp.not (|
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "revm_primitives::specification::Spec",
                                      SPEC,
                                      [],
                                      "enabled",
                                      []
                                    |),
                                    [
                                      Value.StructTuple
                                        "revm_primitives::specification::SpecId::BYZANTIUM"
                                        []
                                    ]
                                  |)
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            M.never_to_any (|
                              M.read (|
                                let~ _ :=
                                  M.write (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| interpreter |),
                                      "revm_interpreter::interpreter::Interpreter",
                                      "instruction_result"
                                    |),
                                    Value.StructTuple
                                      "revm_interpreter::instruction_result::InstructionResult::NotActivated"
                                      []
                                  |) in
                                M.return_ (| Value.Tuple [] |)
                              |)
                            |)
                          |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                    ]
                  |) in
                let~ _ :=
                  M.alloc (|
                    M.call_closure (|
                      M.get_function (|
                        "revm_interpreter::instructions::control::return_inner",
                        []
                      |),
                      [
                        M.read (| interpreter |);
                        Value.StructTuple
                          "revm_interpreter::instruction_result::InstructionResult::Revert"
                          []
                      ]
                    |)
                  |) in
                M.alloc (| Value.Tuple [] |)
              |)))
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_revert : M.IsFunction "revm_interpreter::instructions::control::revert" revert.
    
    (*
    pub fn stop<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        interpreter.instruction_result = InstructionResult::Stop;
    }
    *)
    Definition stop (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.read (|
            let~ _ :=
              M.write (|
                M.SubPointer.get_struct_record_field (|
                  M.read (| interpreter |),
                  "revm_interpreter::interpreter::Interpreter",
                  "instruction_result"
                |),
                Value.StructTuple "revm_interpreter::instruction_result::InstructionResult::Stop" []
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_stop : M.IsFunction "revm_interpreter::instructions::control::stop" stop.
    
    (*
    pub fn invalid<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        interpreter.instruction_result = InstructionResult::InvalidFEOpcode;
    }
    *)
    Definition invalid (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.read (|
            let~ _ :=
              M.write (|
                M.SubPointer.get_struct_record_field (|
                  M.read (| interpreter |),
                  "revm_interpreter::interpreter::Interpreter",
                  "instruction_result"
                |),
                Value.StructTuple
                  "revm_interpreter::instruction_result::InstructionResult::InvalidFEOpcode"
                  []
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_invalid :
      M.IsFunction "revm_interpreter::instructions::control::invalid" invalid.
    
    (*
    pub fn unknown<H: Host + ?Sized>(interpreter: &mut Interpreter, _host: &mut H) {
        interpreter.instruction_result = InstructionResult::OpcodeNotFound;
    }
    *)
    Definition unknown (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      match ε, τ, α with
      | [], [ H ], [ interpreter; _host ] =>
        ltac:(M.monadic
          (let interpreter := M.alloc (| interpreter |) in
          let _host := M.alloc (| _host |) in
          M.read (|
            let~ _ :=
              M.write (|
                M.SubPointer.get_struct_record_field (|
                  M.read (| interpreter |),
                  "revm_interpreter::interpreter::Interpreter",
                  "instruction_result"
                |),
                Value.StructTuple
                  "revm_interpreter::instruction_result::InstructionResult::OpcodeNotFound"
                  []
              |) in
            M.alloc (| Value.Tuple [] |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Function_unknown :
      M.IsFunction "revm_interpreter::instructions::control::unknown" unknown.
  End control.
End instructions.
