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

Module reference_safety.
  Module abstract_state.
    Axiom BorrowGraph :
      (Ty.path "move_bytecode_verifier::reference_safety::abstract_state::BorrowGraph") =
        (Ty.apply
          (Ty.path "move_borrow_graph::graph::BorrowGraph")
          []
          [ Ty.tuple []; Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
          ]).
    
    (*
    Enum AbstractValue
    {
      const_params := [];
      ty_params := [];
      variants :=
        [
          {
            name := "Reference";
            item := StructTuple [ Ty.path "move_borrow_graph::references::RefID" ];
            discriminant := None;
          };
          {
            name := "NonReference";
            item := StructTuple [];
            discriminant := None;
          }
        ];
    }
    *)
    
    Module Impl_core_clone_Clone_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                Value.DeclaredButUndefined,
                [ fun γ => ltac:(M.monadic (M.read (| self |))) ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
    
    Module Impl_core_marker_Copy_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue".
      
      Axiom Implements :
        M.IsTraitInstance
          "core::marker::Copy"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_Copy_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
    
    Module Impl_core_fmt_Debug_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.read (|
              M.match_operator (|
                self,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "debug_tuple_field1_finish",
                            []
                          |),
                          [ M.read (| f |); M.read (| Value.String "Reference" |); __self_0 ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let _ :=
                        M.is_struct_tuple (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                        |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "write_str",
                            []
                          |),
                          [ M.read (| f |); M.read (| Value.String "NonReference" |) ]
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
    
    Module Impl_core_cmp_Eq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue".
      
      (* Eq *)
      Definition assert_receiver_is_total_eq
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                Value.DeclaredButUndefined,
                [ fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |))) ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::Eq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [ ("assert_receiver_is_total_eq", InstanceField.Method assert_receiver_is_total_eq) ].
    End Impl_core_cmp_Eq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
    
    Module Impl_core_marker_StructuralPartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue".
      
      Axiom Implements :
        M.IsTraitInstance
          "core::marker::StructuralPartialEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_StructuralPartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
    
    Module Impl_core_cmp_PartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue".
      
      (* PartialEq *)
      Definition eq (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            M.read (|
              let~ __self_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [
                        Ty.path
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                      ]
                    |),
                    [ M.read (| self |) ]
                  |)
                |) in
              let~ __arg1_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [
                        Ty.path
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                      ]
                    |),
                    [ M.read (| other |) ]
                  |)
                |) in
              M.alloc (|
                LogicalOp.and (|
                  BinOp.eq (| M.read (| __self_discr |), M.read (| __arg1_discr |) |),
                  ltac:(M.monadic
                    (M.read (|
                      M.match_operator (|
                        M.alloc (| Value.Tuple [ M.read (| self |); M.read (| other |) ] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let γ0_0 := M.read (| γ0_0 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                  0
                                |) in
                              let __self_0 := M.alloc (| γ2_0 |) in
                              let γ0_1 := M.read (| γ0_1 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                  0
                                |) in
                              let __arg1_0 := M.alloc (| γ2_0 |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::cmp::PartialEq",
                                    Ty.apply
                                      (Ty.path "&")
                                      []
                                      [ Ty.path "move_borrow_graph::references::RefID" ],
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        []
                                        [ Ty.path "move_borrow_graph::references::RefID" ]
                                    ],
                                    "eq",
                                    []
                                  |),
                                  [ __self_0; __arg1_0 ]
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Bool true |)))
                        ]
                      |)
                    |)))
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::PartialEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("eq", InstanceField.Method eq) ].
    End Impl_core_cmp_PartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
    
    Module Impl_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue".
      
      (*
          pub fn is_reference(&self) -> bool {
              match self {
                  AbstractValue::Reference(_) => true,
                  AbstractValue::NonReference => false,
              }
          }
      *)
      Definition is_reference (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                self,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                          0
                        |) in
                      M.alloc (| Value.Bool true |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let _ :=
                        M.is_struct_tuple (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                        |) in
                      M.alloc (| Value.Bool false |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_reference :
        M.IsAssociatedFunction Self "is_reference" is_reference.
      
      (*
          pub fn is_value(&self) -> bool {
              !self.is_reference()
          }
      *)
      Definition is_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            UnOp.not (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue",
                  "is_reference",
                  []
                |),
                [ M.read (| self |) ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_value : M.IsAssociatedFunction Self "is_value" is_value.
      
      (*
          pub fn ref_id(&self) -> Option<RefID> {
              match self {
                  AbstractValue::Reference(id) => Some( *id),
                  AbstractValue::NonReference => None,
              }
          }
      *)
      Definition ref_id (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                self,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                          0
                        |) in
                      let id := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        Value.StructTuple
                          "core::option::Option::Some"
                          [ M.read (| M.read (| id |) |) ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let _ :=
                        M.is_struct_tuple (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                        |) in
                      M.alloc (| Value.StructTuple "core::option::Option::None" [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_ref_id : M.IsAssociatedFunction Self "ref_id" ref_id.
    End Impl_move_bytecode_verifier_reference_safety_abstract_state_AbstractValue.
    
    (*
    Enum Label
    {
      const_params := [];
      ty_params := [];
      variants :=
        [
          {
            name := "Local";
            item := StructTuple [ Ty.path "u8" ];
            discriminant := None;
          };
          {
            name := "Global";
            item :=
              StructTuple [ Ty.path "move_binary_format::file_format::StructDefinitionIndex" ];
            discriminant := None;
          };
          {
            name := "Field";
            item := StructTuple [ Ty.path "move_binary_format::file_format::FieldHandleIndex" ];
            discriminant := None;
          }
        ];
    }
    *)
    
    Module Impl_core_clone_Clone_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                self,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Local",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Local"
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::clone::Clone",
                                Ty.path "u8",
                                [],
                                "clone",
                                []
                              |),
                              [ M.read (| __self_0 |) ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Global",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Global"
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::clone::Clone",
                                Ty.path "move_binary_format::file_format::StructDefinitionIndex",
                                [],
                                "clone",
                                []
                              |),
                              [ M.read (| __self_0 |) ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Field",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Field"
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::clone::Clone",
                                Ty.path "move_binary_format::file_format::FieldHandleIndex",
                                [],
                                "clone",
                                []
                              |),
                              [ M.read (| __self_0 |) ]
                            |)
                          ]
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
    
    Module Impl_core_fmt_Debug_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.read (|
              M.match_operator (|
                self,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Local",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "debug_tuple_field1_finish",
                            []
                          |),
                          [ M.read (| f |); M.read (| Value.String "Local" |); __self_0 ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Global",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "debug_tuple_field1_finish",
                            []
                          |),
                          [ M.read (| f |); M.read (| Value.String "Global" |); __self_0 ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Field",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "debug_tuple_field1_finish",
                            []
                          |),
                          [ M.read (| f |); M.read (| Value.String "Field" |); __self_0 ]
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
    
    Module Impl_core_cmp_Eq_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label".
      
      (* Eq *)
      Definition assert_receiver_is_total_eq
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                Value.DeclaredButUndefined,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (M.match_operator (|
                        Value.DeclaredButUndefined,
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (M.match_operator (|
                                Value.DeclaredButUndefined,
                                [ fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |))) ]
                              |)))
                        ]
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::Eq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [ ("assert_receiver_is_total_eq", InstanceField.Method assert_receiver_is_total_eq) ].
    End Impl_core_cmp_Eq_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
    
    Module Impl_core_cmp_Ord_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label".
      
      (* Ord *)
      Definition cmp (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            M.read (|
              let~ __self_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [ Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label" ]
                    |),
                    [ M.read (| self |) ]
                  |)
                |) in
              let~ __arg1_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [ Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label" ]
                    |),
                    [ M.read (| other |) ]
                  |)
                |) in
              M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (| "core::cmp::Ord", Ty.path "isize", [], "cmp", [] |),
                    [ __self_discr; __arg1_discr ]
                  |)
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let _ := M.is_struct_tuple (| γ, "core::cmp::Ordering::Equal" |) in
                      M.match_operator (|
                        M.alloc (| Value.Tuple [ M.read (| self |); M.read (| other |) ] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let γ0_0 := M.read (| γ0_0 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Local",
                                  0
                                |) in
                              let __self_0 := M.alloc (| γ2_0 |) in
                              let γ0_1 := M.read (| γ0_1 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Local",
                                  0
                                |) in
                              let __arg1_0 := M.alloc (| γ2_0 |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::cmp::Ord",
                                    Ty.path "u8",
                                    [],
                                    "cmp",
                                    []
                                  |),
                                  [ M.read (| __self_0 |); M.read (| __arg1_0 |) ]
                                |)
                              |)));
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let γ0_0 := M.read (| γ0_0 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Global",
                                  0
                                |) in
                              let __self_0 := M.alloc (| γ2_0 |) in
                              let γ0_1 := M.read (| γ0_1 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Global",
                                  0
                                |) in
                              let __arg1_0 := M.alloc (| γ2_0 |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::cmp::Ord",
                                    Ty.path
                                      "move_binary_format::file_format::StructDefinitionIndex",
                                    [],
                                    "cmp",
                                    []
                                  |),
                                  [ M.read (| __self_0 |); M.read (| __arg1_0 |) ]
                                |)
                              |)));
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let γ0_0 := M.read (| γ0_0 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Field",
                                  0
                                |) in
                              let __self_0 := M.alloc (| γ2_0 |) in
                              let γ0_1 := M.read (| γ0_1 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Field",
                                  0
                                |) in
                              let __arg1_0 := M.alloc (| γ2_0 |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::cmp::Ord",
                                    Ty.path "move_binary_format::file_format::FieldHandleIndex",
                                    [],
                                    "cmp",
                                    []
                                  |),
                                  [ M.read (| __self_0 |); M.read (| __arg1_0 |) ]
                                |)
                              |)));
                          fun γ =>
                            ltac:(M.monadic
                              (M.alloc (|
                                M.never_to_any (|
                                  M.call_closure (|
                                    M.get_function (| "core::intrinsics::unreachable", [] |),
                                    []
                                  |)
                                |)
                              |)))
                        ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let cmp := M.copy (| γ |) in
                      cmp))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::Ord"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("cmp", InstanceField.Method cmp) ].
    End Impl_core_cmp_Ord_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
    
    Module Impl_core_marker_StructuralPartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label".
      
      Axiom Implements :
        M.IsTraitInstance
          "core::marker::StructuralPartialEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_StructuralPartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
    
    Module Impl_core_cmp_PartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label".
      
      (* PartialEq *)
      Definition eq (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            M.read (|
              let~ __self_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [ Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label" ]
                    |),
                    [ M.read (| self |) ]
                  |)
                |) in
              let~ __arg1_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [ Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label" ]
                    |),
                    [ M.read (| other |) ]
                  |)
                |) in
              M.alloc (|
                LogicalOp.and (|
                  BinOp.eq (| M.read (| __self_discr |), M.read (| __arg1_discr |) |),
                  ltac:(M.monadic
                    (M.read (|
                      M.match_operator (|
                        M.alloc (| Value.Tuple [ M.read (| self |); M.read (| other |) ] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let γ0_0 := M.read (| γ0_0 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Local",
                                  0
                                |) in
                              let __self_0 := M.alloc (| γ2_0 |) in
                              let γ0_1 := M.read (| γ0_1 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Local",
                                  0
                                |) in
                              let __arg1_0 := M.alloc (| γ2_0 |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::cmp::PartialEq",
                                    Ty.apply (Ty.path "&") [] [ Ty.path "u8" ],
                                    [ Ty.apply (Ty.path "&") [] [ Ty.path "u8" ] ],
                                    "eq",
                                    []
                                  |),
                                  [ __self_0; __arg1_0 ]
                                |)
                              |)));
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let γ0_0 := M.read (| γ0_0 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Global",
                                  0
                                |) in
                              let __self_0 := M.alloc (| γ2_0 |) in
                              let γ0_1 := M.read (| γ0_1 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Global",
                                  0
                                |) in
                              let __arg1_0 := M.alloc (| γ2_0 |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::cmp::PartialEq",
                                    Ty.apply
                                      (Ty.path "&")
                                      []
                                      [
                                        Ty.path
                                          "move_binary_format::file_format::StructDefinitionIndex"
                                      ],
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        []
                                        [
                                          Ty.path
                                            "move_binary_format::file_format::StructDefinitionIndex"
                                        ]
                                    ],
                                    "eq",
                                    []
                                  |),
                                  [ __self_0; __arg1_0 ]
                                |)
                              |)));
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                              let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                              let γ0_0 := M.read (| γ0_0 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_0,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Field",
                                  0
                                |) in
                              let __self_0 := M.alloc (| γ2_0 |) in
                              let γ0_1 := M.read (| γ0_1 |) in
                              let γ2_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ0_1,
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Field",
                                  0
                                |) in
                              let __arg1_0 := M.alloc (| γ2_0 |) in
                              M.alloc (|
                                M.call_closure (|
                                  M.get_trait_method (|
                                    "core::cmp::PartialEq",
                                    Ty.apply
                                      (Ty.path "&")
                                      []
                                      [ Ty.path "move_binary_format::file_format::FieldHandleIndex"
                                      ],
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        []
                                        [
                                          Ty.path
                                            "move_binary_format::file_format::FieldHandleIndex"
                                        ]
                                    ],
                                    "eq",
                                    []
                                  |),
                                  [ __self_0; __arg1_0 ]
                                |)
                              |)));
                          fun γ =>
                            ltac:(M.monadic
                              (M.alloc (|
                                M.never_to_any (|
                                  M.call_closure (|
                                    M.get_function (| "core::intrinsics::unreachable", [] |),
                                    []
                                  |)
                                |)
                              |)))
                        ]
                      |)
                    |)))
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::PartialEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("eq", InstanceField.Method eq) ].
    End Impl_core_cmp_PartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
    
    Module Impl_core_cmp_PartialOrd_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label".
      
      (* PartialOrd *)
      Definition partial_cmp (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            M.read (|
              let~ __self_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [ Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label" ]
                    |),
                    [ M.read (| self |) ]
                  |)
                |) in
              let~ __arg1_discr :=
                M.alloc (|
                  M.call_closure (|
                    M.get_function (|
                      "core::intrinsics::discriminant_value",
                      [ Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label" ]
                    |),
                    [ M.read (| other |) ]
                  |)
                |) in
              M.match_operator (|
                M.alloc (| Value.Tuple [ M.read (| self |); M.read (| other |) ] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                      let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                      let γ0_0 := M.read (| γ0_0 |) in
                      let γ2_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ0_0,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Local",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ2_0 |) in
                      let γ0_1 := M.read (| γ0_1 |) in
                      let γ2_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ0_1,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Local",
                          0
                        |) in
                      let __arg1_0 := M.alloc (| γ2_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::cmp::PartialOrd",
                            Ty.path "u8",
                            [ Ty.path "u8" ],
                            "partial_cmp",
                            []
                          |),
                          [ M.read (| __self_0 |); M.read (| __arg1_0 |) ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                      let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                      let γ0_0 := M.read (| γ0_0 |) in
                      let γ2_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ0_0,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Global",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ2_0 |) in
                      let γ0_1 := M.read (| γ0_1 |) in
                      let γ2_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ0_1,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Global",
                          0
                        |) in
                      let __arg1_0 := M.alloc (| γ2_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::cmp::PartialOrd",
                            Ty.path "move_binary_format::file_format::StructDefinitionIndex",
                            [ Ty.path "move_binary_format::file_format::StructDefinitionIndex" ],
                            "partial_cmp",
                            []
                          |),
                          [ M.read (| __self_0 |); M.read (| __arg1_0 |) ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                      let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                      let γ0_0 := M.read (| γ0_0 |) in
                      let γ2_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ0_0,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Field",
                          0
                        |) in
                      let __self_0 := M.alloc (| γ2_0 |) in
                      let γ0_1 := M.read (| γ0_1 |) in
                      let γ2_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ0_1,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Field",
                          0
                        |) in
                      let __arg1_0 := M.alloc (| γ2_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::cmp::PartialOrd",
                            Ty.path "move_binary_format::file_format::FieldHandleIndex",
                            [ Ty.path "move_binary_format::file_format::FieldHandleIndex" ],
                            "partial_cmp",
                            []
                          |),
                          [ M.read (| __self_0 |); M.read (| __arg1_0 |) ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::cmp::PartialOrd",
                            Ty.path "isize",
                            [ Ty.path "isize" ],
                            "partial_cmp",
                            []
                          |),
                          [ __self_discr; __arg1_discr ]
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::PartialOrd"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("partial_cmp", InstanceField.Method partial_cmp) ].
    End Impl_core_cmp_PartialOrd_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
    
    Module Impl_core_fmt_Display_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label".
      
      (*
          fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
              match self {
                  Label::Local(i) => write!(f, "local#{}", i),
                  Label::Global(i) => write!(f, "resource@{}", i),
                  Label::Field(i) => write!(f, "field#{}", i),
              }
          }
      *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.read (|
              M.match_operator (|
                self,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Local",
                          0
                        |) in
                      let i := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "write_fmt",
                            []
                          |),
                          [
                            M.read (| f |);
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "core::fmt::Arguments",
                                "new_v1",
                                []
                              |),
                              [
                                M.alloc (| Value.Array [ M.read (| Value.String "local#" |) ] |);
                                M.alloc (|
                                  Value.Array
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "core::fmt::rt::Argument",
                                          "new_display",
                                          [ Ty.apply (Ty.path "&") [] [ Ty.path "u8" ] ]
                                        |),
                                        [ i ]
                                      |)
                                    ]
                                |)
                              ]
                            |)
                          ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Global",
                          0
                        |) in
                      let i := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "write_fmt",
                            []
                          |),
                          [
                            M.read (| f |);
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "core::fmt::Arguments",
                                "new_v1",
                                []
                              |),
                              [
                                M.alloc (| Value.Array [ M.read (| Value.String "resource@" |) ] |);
                                M.alloc (|
                                  Value.Array
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "core::fmt::rt::Argument",
                                          "new_display",
                                          [
                                            Ty.apply
                                              (Ty.path "&")
                                              []
                                              [
                                                Ty.path
                                                  "move_binary_format::file_format::StructDefinitionIndex"
                                              ]
                                          ]
                                        |),
                                        [ i ]
                                      |)
                                    ]
                                |)
                              ]
                            |)
                          ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::Label::Field",
                          0
                        |) in
                      let i := M.alloc (| γ1_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::Formatter",
                            "write_fmt",
                            []
                          |),
                          [
                            M.read (| f |);
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path "core::fmt::Arguments",
                                "new_v1",
                                []
                              |),
                              [
                                M.alloc (| Value.Array [ M.read (| Value.String "field#" |) ] |);
                                M.alloc (|
                                  Value.Array
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "core::fmt::rt::Argument",
                                          "new_display",
                                          [
                                            Ty.apply
                                              (Ty.path "&")
                                              []
                                              [
                                                Ty.path
                                                  "move_binary_format::file_format::FieldHandleIndex"
                                              ]
                                          ]
                                        |),
                                        [ i ]
                                      |)
                                    ]
                                |)
                              ]
                            |)
                          ]
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Display"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Display_for_move_bytecode_verifier_reference_safety_abstract_state_Label.
    
    Definition value_STEP_BASE_COST : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 10 |))).
    
    Definition value_STEP_PER_LOCAL_COST : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 20 |))).
    
    Definition value_STEP_PER_GRAPH_ITEM_COST : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 50 |))).
    
    Definition value_JOIN_BASE_COST : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 100 |))).
    
    Definition value_JOIN_PER_LOCAL_COST : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 10 |))).
    
    Definition value_JOIN_PER_GRAPH_ITEM_COST : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 50 |))).
    
    Definition value_REF_PARAM_EDGE_COST : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 100 |))).
    
    Definition value_REF_PARAM_EDGE_COST_GROWTH : Value.t :=
      M.run ltac:(M.monadic UnsupportedLiteral).
    
    Definition value_CALL_PER_ACQUIRES_COST : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 100 |))).
    
    (* StructRecord
      {
        name := "AbstractState";
        const_params := [];
        ty_params := [];
        fields :=
          [
            ("current_function",
              Ty.apply
                (Ty.path "core::option::Option")
                []
                [ Ty.path "move_binary_format::file_format::FunctionDefinitionIndex" ]);
            ("locals",
              Ty.apply
                (Ty.path "alloc::vec::Vec")
                []
                [
                  Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                  Ty.path "alloc::alloc::Global"
                ]);
            ("borrow_graph",
              Ty.apply
                (Ty.path "move_borrow_graph::graph::BorrowGraph")
                []
                [
                  Ty.tuple [];
                  Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                ]);
            ("next_id", Ty.path "usize")
          ];
      } *)
    
    Module Impl_core_clone_Clone_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState".
      
      (* Clone *)
      Definition clone (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            Value.StructRecord
              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState"
              [
                ("current_function",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply
                        (Ty.path "core::option::Option")
                        []
                        [ Ty.path "move_binary_format::file_format::FunctionDefinitionIndex" ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "current_function"
                      |)
                    ]
                  |));
                ("locals",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                          Ty.path "alloc::alloc::Global"
                        ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "locals"
                      |)
                    ]
                  |));
                ("borrow_graph",
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |)
                    ]
                  |));
                ("next_id",
                  M.call_closure (|
                    M.get_trait_method (| "core::clone::Clone", Ty.path "usize", [], "clone", [] |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "next_id"
                      |)
                    ]
                  |))
              ]))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::clone::Clone"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("clone", InstanceField.Method clone) ].
    End Impl_core_clone_Clone_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
    
    Module Impl_core_fmt_Debug_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState".
      
      (* Debug *)
      Definition fmt (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; f ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let f := M.alloc (| f |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "core::fmt::Formatter",
                "debug_struct_field4_finish",
                []
              |),
              [
                M.read (| f |);
                M.read (| Value.String "AbstractState" |);
                M.read (| Value.String "current_function" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "current_function"
                |);
                M.read (| Value.String "locals" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "locals"
                |);
                M.read (| Value.String "borrow_graph" |);
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "borrow_graph"
                |);
                M.read (| Value.String "next_id" |);
                M.alloc (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "next_id"
                  |)
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::fmt::Debug"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("fmt", InstanceField.Method fmt) ].
    End Impl_core_fmt_Debug_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
    
    Module Impl_core_marker_StructuralPartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState".
      
      Axiom Implements :
        M.IsTraitInstance
          "core::marker::StructuralPartialEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [].
    End Impl_core_marker_StructuralPartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
    
    Module Impl_core_cmp_PartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState".
      
      (* PartialEq *)
      Definition eq (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            LogicalOp.and (|
              LogicalOp.and (|
                LogicalOp.and (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::cmp::PartialEq",
                      Ty.apply
                        (Ty.path "core::option::Option")
                        []
                        [ Ty.path "move_binary_format::file_format::FunctionDefinitionIndex" ],
                      [
                        Ty.apply
                          (Ty.path "core::option::Option")
                          []
                          [ Ty.path "move_binary_format::file_format::FunctionDefinitionIndex" ]
                      ],
                      "eq",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "current_function"
                      |);
                      M.SubPointer.get_struct_record_field (|
                        M.read (| other |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "current_function"
                      |)
                    ]
                  |),
                  ltac:(M.monadic
                    (M.call_closure (|
                      M.get_trait_method (|
                        "core::cmp::PartialEq",
                        Ty.apply
                          (Ty.path "alloc::vec::Vec")
                          []
                          [
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                            Ty.path "alloc::alloc::Global"
                          ],
                        [
                          Ty.apply
                            (Ty.path "alloc::vec::Vec")
                            []
                            [
                              Ty.path
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                              Ty.path "alloc::alloc::Global"
                            ]
                        ],
                        "eq",
                        []
                      |),
                      [
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "locals"
                        |);
                        M.SubPointer.get_struct_record_field (|
                          M.read (| other |),
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "locals"
                        |)
                      ]
                    |)))
                |),
                ltac:(M.monadic
                  (M.call_closure (|
                    M.get_trait_method (|
                      "core::cmp::PartialEq",
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      [
                        Ty.apply
                          (Ty.path "move_borrow_graph::graph::BorrowGraph")
                          []
                          [
                            Ty.tuple [];
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::Label"
                          ]
                      ],
                      "eq",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |);
                      M.SubPointer.get_struct_record_field (|
                        M.read (| other |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |)
                    ]
                  |)))
              |),
              ltac:(M.monadic
                (BinOp.eq (|
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                      "next_id"
                    |)
                  |),
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      M.read (| other |),
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                      "next_id"
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::PartialEq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("eq", InstanceField.Method eq) ].
    End Impl_core_cmp_PartialEq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
    
    Module Impl_core_cmp_Eq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState".
      
      (* Eq *)
      Definition assert_receiver_is_total_eq
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              M.match_operator (|
                Value.DeclaredButUndefined,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (M.match_operator (|
                        Value.DeclaredButUndefined,
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (M.match_operator (|
                                Value.DeclaredButUndefined,
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (M.match_operator (|
                                        Value.DeclaredButUndefined,
                                        [ fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |))) ]
                                      |)))
                                ]
                              |)))
                        ]
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "core::cmp::Eq"
          Self
          (* Trait polymorphic types *) []
          (* Instance *)
          [ ("assert_receiver_is_total_eq", InstanceField.Method assert_receiver_is_total_eq) ].
    End Impl_core_cmp_Eq_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
    
    Module Impl_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState".
      
      (*
          pub fn new(function_context: &FunctionContext) -> Self {
              let num_locals = function_context.parameters().len() + function_context.locals().len();
              // ids in [0, num_locals) are reserved for constructing canonical state
              // id at num_locals is reserved for the frame root
              let next_id = num_locals + 1;
              let mut state = AbstractState {
                  current_function: function_context.index(),
                  locals: vec![AbstractValue::NonReference; num_locals],
                  borrow_graph: BorrowGraph::new(),
                  next_id,
              };
      
              for (param_idx, param_ty) in function_context.parameters().0.iter().enumerate() {
                  if param_ty.is_reference() {
                      let id = RefID::new(param_idx);
                      state
                          .borrow_graph
                          .new_ref(id, param_ty.is_mutable_reference());
                      state.locals[param_idx] = AbstractValue::Reference(id)
                  }
              }
              state.borrow_graph.new_ref(state.frame_root(), true);
      
              assert!(state.is_canonical());
              state
          }
      *)
      Definition new (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ function_context ] =>
          ltac:(M.monadic
            (let function_context := M.alloc (| function_context |) in
            M.read (|
              let~ num_locals :=
                M.alloc (|
                  BinOp.Wrap.add (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "move_binary_format::file_format::Signature",
                        "len",
                        []
                      |),
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "move_bytecode_verifier::absint::FunctionContext",
                            "parameters",
                            []
                          |),
                          [ M.read (| function_context |) ]
                        |)
                      ]
                    |),
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.path "move_binary_format::file_format::Signature",
                        "len",
                        []
                      |),
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "move_bytecode_verifier::absint::FunctionContext",
                            "locals",
                            []
                          |),
                          [ M.read (| function_context |) ]
                        |)
                      ]
                    |)
                  |)
                |) in
              let~ next_id :=
                M.alloc (|
                  BinOp.Wrap.add (| M.read (| num_locals |), Value.Integer IntegerKind.Usize 1 |)
                |) in
              let~ state :=
                M.alloc (|
                  Value.StructRecord
                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState"
                    [
                      ("current_function",
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "move_bytecode_verifier::absint::FunctionContext",
                            "index",
                            []
                          |),
                          [ M.read (| function_context |) ]
                        |));
                      ("locals",
                        M.call_closure (|
                          M.get_function (|
                            "alloc::vec::from_elem",
                            [
                              Ty.path
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                            ]
                          |),
                          [
                            Value.StructTuple
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                              [];
                            M.read (| num_locals |)
                          ]
                        |));
                      ("borrow_graph",
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply
                              (Ty.path "move_borrow_graph::graph::BorrowGraph")
                              []
                              [
                                Ty.tuple [];
                                Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::Label"
                              ],
                            "new",
                            []
                          |),
                          []
                        |));
                      ("next_id", M.read (| next_id |))
                    ]
                |) in
              let~ _ :=
                M.use
                  (M.match_operator (|
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::collect::IntoIterator",
                          Ty.apply
                            (Ty.path "core::iter::adapters::enumerate::Enumerate")
                            []
                            [
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [ Ty.path "move_binary_format::file_format::SignatureToken" ]
                            ],
                          [],
                          "into_iter",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [ Ty.path "move_binary_format::file_format::SignatureToken" ],
                              [],
                              "enumerate",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    []
                                    [ Ty.path "move_binary_format::file_format::SignatureToken" ],
                                  "iter",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::deref::Deref",
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path "move_binary_format::file_format::SignatureToken";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      [],
                                      "deref",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_tuple_field (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::absint::FunctionContext",
                                            "parameters",
                                            []
                                          |),
                                          [ M.read (| function_context |) ]
                                        |),
                                        "move_binary_format::file_format::Signature",
                                        0
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        ]
                      |)
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let iter := M.copy (| γ |) in
                          M.loop (|
                            ltac:(M.monadic
                              (let~ _ :=
                                M.match_operator (|
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::iter::traits::iterator::Iterator",
                                        Ty.apply
                                          (Ty.path "core::iter::adapters::enumerate::Enumerate")
                                          []
                                          [
                                            Ty.apply
                                              (Ty.path "core::slice::iter::Iter")
                                              []
                                              [
                                                Ty.path
                                                  "move_binary_format::file_format::SignatureToken"
                                              ]
                                          ],
                                        [],
                                        "next",
                                        []
                                      |),
                                      [ iter ]
                                    |)
                                  |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let _ :=
                                          M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                        M.alloc (|
                                          M.never_to_any (| M.read (| M.break (||) |) |)
                                        |)));
                                    fun γ =>
                                      ltac:(M.monadic
                                        (let γ0_0 :=
                                          M.SubPointer.get_struct_tuple_field (|
                                            γ,
                                            "core::option::Option::Some",
                                            0
                                          |) in
                                        let γ1_0 := M.SubPointer.get_tuple_field (| γ0_0, 0 |) in
                                        let γ1_1 := M.SubPointer.get_tuple_field (| γ0_0, 1 |) in
                                        let param_idx := M.copy (| γ1_0 |) in
                                        let param_ty := M.copy (| γ1_1 |) in
                                        M.match_operator (|
                                          M.alloc (| Value.Tuple [] |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ :=
                                                  M.use
                                                    (M.alloc (|
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.path
                                                            "move_binary_format::file_format::SignatureToken",
                                                          "is_reference",
                                                          []
                                                        |),
                                                        [ M.read (| param_ty |) ]
                                                      |)
                                                    |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                let~ id :=
                                                  M.alloc (|
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "move_borrow_graph::references::RefID",
                                                        "new",
                                                        []
                                                      |),
                                                      [ M.read (| param_idx |) ]
                                                    |)
                                                  |) in
                                                let~ _ :=
                                                  M.alloc (|
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.apply
                                                          (Ty.path
                                                            "move_borrow_graph::graph::BorrowGraph")
                                                          []
                                                          [
                                                            Ty.tuple [];
                                                            Ty.path
                                                              "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                                          ],
                                                        "new_ref",
                                                        []
                                                      |),
                                                      [
                                                        M.SubPointer.get_struct_record_field (|
                                                          state,
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                          "borrow_graph"
                                                        |);
                                                        M.read (| id |);
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path
                                                              "move_binary_format::file_format::SignatureToken",
                                                            "is_mutable_reference",
                                                            []
                                                          |),
                                                          [ M.read (| param_ty |) ]
                                                        |)
                                                      ]
                                                    |)
                                                  |) in
                                                M.write (|
                                                  M.call_closure (|
                                                    M.get_trait_method (|
                                                      "core::ops::index::IndexMut",
                                                      Ty.apply
                                                        (Ty.path "alloc::vec::Vec")
                                                        []
                                                        [
                                                          Ty.path
                                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                                          Ty.path "alloc::alloc::Global"
                                                        ],
                                                      [ Ty.path "usize" ],
                                                      "index_mut",
                                                      []
                                                    |),
                                                    [
                                                      M.SubPointer.get_struct_record_field (|
                                                        state,
                                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                        "locals"
                                                      |);
                                                      M.read (| param_idx |)
                                                    ]
                                                  |),
                                                  Value.StructTuple
                                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                                                    [ M.read (| id |) ]
                                                |)));
                                            fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                          ]
                                        |)))
                                  ]
                                |) in
                              M.alloc (| Value.Tuple [] |)))
                          |)))
                    ]
                  |)) in
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      "new_ref",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        state,
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |);
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "frame_root",
                          []
                        |),
                        [ state ]
                      |);
                      Value.Bool true
                    ]
                  |)
                |) 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
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                    "is_canonical",
                                    []
                                  |),
                                  [ state ]
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.never_to_any (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic", [] |),
                              [ M.read (| Value.String "assertion failed: state.is_canonical()" |) ]
                            |)
                          |)
                        |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |) in
              state
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_new : M.IsAssociatedFunction Self "new" new.
      
      (*
          pub(crate) fn local_count(&self) -> usize {
              self.locals.len()
          }
      *)
      Definition local_count (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "alloc::vec::Vec")
                  []
                  [
                    Ty.path
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                    Ty.path "alloc::alloc::Global"
                  ],
                "len",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "locals"
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_local_count : M.IsAssociatedFunction Self "local_count" local_count.
      
      (*
          pub(crate) fn graph_size(&self) -> usize {
              self.borrow_graph.graph_size()
          }
      *)
      Definition graph_size (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "move_borrow_graph::graph::BorrowGraph")
                  []
                  [
                    Ty.tuple [];
                    Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                  ],
                "graph_size",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "borrow_graph"
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_graph_size : M.IsAssociatedFunction Self "graph_size" graph_size.
      
      (*
          fn frame_root(&self) -> RefID {
              RefID::new(self.locals.len())
          }
      *)
      Definition frame_root (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "move_borrow_graph::references::RefID",
                "new",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply
                      (Ty.path "alloc::vec::Vec")
                      []
                      [
                        Ty.path
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                        Ty.path "alloc::alloc::Global"
                      ],
                    "len",
                    []
                  |),
                  [
                    M.SubPointer.get_struct_record_field (|
                      M.read (| self |),
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                      "locals"
                    |)
                  ]
                |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_frame_root : M.IsAssociatedFunction Self "frame_root" frame_root.
      
      (*
          fn error(&self, status: StatusCode, offset: CodeOffset) -> PartialVMError {
              PartialVMError::new(status).at_code_offset(
                  self.current_function.unwrap_or(FunctionDefinitionIndex(0)),
                  offset,
              )
          }
      *)
      Definition error (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; status; offset ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let status := M.alloc (| status |) in
            let offset := M.alloc (| offset |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "move_binary_format::errors::PartialVMError",
                "at_code_offset",
                []
              |),
              [
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path "move_binary_format::errors::PartialVMError",
                    "new",
                    []
                  |),
                  [ M.read (| status |) ]
                |);
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply
                      (Ty.path "core::option::Option")
                      []
                      [ Ty.path "move_binary_format::file_format::FunctionDefinitionIndex" ],
                    "unwrap_or",
                    []
                  |),
                  [
                    M.read (|
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "current_function"
                      |)
                    |);
                    Value.StructTuple
                      "move_binary_format::file_format::FunctionDefinitionIndex"
                      [ Value.Integer IntegerKind.U16 0 ]
                  ]
                |);
                M.read (| offset |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_error : M.IsAssociatedFunction Self "error" error.
      
      (*
          pub fn value_for(&mut self, s: &SignatureToken) -> AbstractValue {
              match s {
                  SignatureToken::Reference(_) => AbstractValue::Reference(self.new_ref(false)),
                  SignatureToken::MutableReference(_) => AbstractValue::Reference(self.new_ref(true)),
                  _ => AbstractValue::NonReference,
              }
          }
      *)
      Definition value_for (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; s ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let s := M.alloc (| s |) in
            M.read (|
              M.match_operator (|
                s,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_binary_format::file_format::SignatureToken::Reference",
                          0
                        |) in
                      M.alloc (|
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                "new_ref",
                                []
                              |),
                              [ M.read (| self |); Value.Bool false ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let γ := M.read (| γ |) in
                      let γ1_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_binary_format::file_format::SignatureToken::MutableReference",
                          0
                        |) in
                      M.alloc (|
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                "new_ref",
                                []
                              |),
                              [ M.read (| self |); Value.Bool true ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (|
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                          []
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_value_for : M.IsAssociatedFunction Self "value_for" value_for.
      
      (*
          fn new_ref(&mut self, mut_: bool) -> RefID {
              let id = RefID::new(self.next_id);
              self.borrow_graph.new_ref(id, mut_);
              self.next_id += 1;
              id
          }
      *)
      Definition new_ref (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; mut_ ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let mut_ := M.alloc (| mut_ |) in
            M.read (|
              let~ id :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path "move_borrow_graph::references::RefID",
                      "new",
                      []
                    |),
                    [
                      M.read (|
                        M.SubPointer.get_struct_record_field (|
                          M.read (| self |),
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "next_id"
                        |)
                      |)
                    ]
                  |)
                |) in
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      "new_ref",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |);
                      M.read (| id |);
                      M.read (| mut_ |)
                    ]
                  |)
                |) in
              let~ _ :=
                let β :=
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "next_id"
                  |) in
                M.write (|
                  β,
                  BinOp.Wrap.add (| M.read (| β |), Value.Integer IntegerKind.Usize 1 |)
                |) in
              id
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_new_ref : M.IsAssociatedFunction Self "new_ref" new_ref.
      
      (*
          fn add_copy(&mut self, parent: RefID, child: RefID) {
              self.borrow_graph.add_strong_borrow((), parent, child)
          }
      *)
      Definition add_copy (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; parent; child ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let parent := M.alloc (| parent |) in
            let child := M.alloc (| child |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "move_borrow_graph::graph::BorrowGraph")
                  []
                  [
                    Ty.tuple [];
                    Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                  ],
                "add_strong_borrow",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "borrow_graph"
                |);
                Value.Tuple [];
                M.read (| parent |);
                M.read (| child |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_add_copy : M.IsAssociatedFunction Self "add_copy" add_copy.
      
      (*
          fn add_borrow(&mut self, parent: RefID, child: RefID) {
              self.borrow_graph.add_weak_borrow((), parent, child)
          }
      *)
      Definition add_borrow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; parent; child ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let parent := M.alloc (| parent |) in
            let child := M.alloc (| child |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "move_borrow_graph::graph::BorrowGraph")
                  []
                  [
                    Ty.tuple [];
                    Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                  ],
                "add_weak_borrow",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "borrow_graph"
                |);
                Value.Tuple [];
                M.read (| parent |);
                M.read (| child |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_add_borrow : M.IsAssociatedFunction Self "add_borrow" add_borrow.
      
      (*
          fn add_field_borrow(&mut self, parent: RefID, field: FieldHandleIndex, child: RefID) {
              self.borrow_graph
                  .add_strong_field_borrow((), parent, Label::Field(field), child)
          }
      *)
      Definition add_field_borrow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; parent; field; child ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let parent := M.alloc (| parent |) in
            let field := M.alloc (| field |) in
            let child := M.alloc (| child |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "move_borrow_graph::graph::BorrowGraph")
                  []
                  [
                    Ty.tuple [];
                    Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                  ],
                "add_strong_field_borrow",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "borrow_graph"
                |);
                Value.Tuple [];
                M.read (| parent |);
                Value.StructTuple
                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Field"
                  [ M.read (| field |) ];
                M.read (| child |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_add_field_borrow :
        M.IsAssociatedFunction Self "add_field_borrow" add_field_borrow.
      
      (*
          fn add_local_borrow(&mut self, local: LocalIndex, id: RefID) {
              self.borrow_graph
                  .add_strong_field_borrow((), self.frame_root(), Label::Local(local), id)
          }
      *)
      Definition add_local_borrow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; local; id ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let local := M.alloc (| local |) in
            let id := M.alloc (| id |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "move_borrow_graph::graph::BorrowGraph")
                  []
                  [
                    Ty.tuple [];
                    Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                  ],
                "add_strong_field_borrow",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "borrow_graph"
                |);
                Value.Tuple [];
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "frame_root",
                    []
                  |),
                  [ M.read (| self |) ]
                |);
                Value.StructTuple
                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Local"
                  [ M.read (| local |) ];
                M.read (| id |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_add_local_borrow :
        M.IsAssociatedFunction Self "add_local_borrow" add_local_borrow.
      
      (*
          fn add_resource_borrow(&mut self, resource: StructDefinitionIndex, id: RefID) {
              self.borrow_graph
                  .add_weak_field_borrow((), self.frame_root(), Label::Global(resource), id)
          }
      *)
      Definition add_resource_borrow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; resource; id ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let resource := M.alloc (| resource |) in
            let id := M.alloc (| id |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.apply
                  (Ty.path "move_borrow_graph::graph::BorrowGraph")
                  []
                  [
                    Ty.tuple [];
                    Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                  ],
                "add_weak_field_borrow",
                []
              |),
              [
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "borrow_graph"
                |);
                Value.Tuple [];
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "frame_root",
                    []
                  |),
                  [ M.read (| self |) ]
                |);
                Value.StructTuple
                  "move_bytecode_verifier::reference_safety::abstract_state::Label::Global"
                  [ M.read (| resource |) ];
                M.read (| id |)
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_add_resource_borrow :
        M.IsAssociatedFunction Self "add_resource_borrow" add_resource_borrow.
      
      (*
          fn release(&mut self, id: RefID) {
              self.borrow_graph.release(id);
          }
      *)
      Definition release (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; id ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let id := M.alloc (| id |) in
            M.read (|
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      "release",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |);
                      M.read (| id |)
                    ]
                  |)
                |) in
              M.alloc (| Value.Tuple [] |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_release : M.IsAssociatedFunction Self "release" release.
      
      (*
          fn has_full_borrows(&self, id: RefID) -> bool {
              let (full_borrows, _field_borrows) = self.borrow_graph.borrowed_by(id);
              !full_borrows.is_empty()
          }
      *)
      Definition has_full_borrows (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; id ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let id := M.alloc (| id |) in
            M.read (|
              M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      "borrowed_by",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |);
                      M.read (| id |)
                    ]
                  |)
                |),
                [
                  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 full_borrows := M.copy (| γ0_0 |) in
                      let _field_borrows := M.copy (| γ0_1 |) in
                      M.alloc (|
                        UnOp.not (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "alloc::collections::btree::map::BTreeMap")
                                []
                                [
                                  Ty.path "move_borrow_graph::references::RefID";
                                  Ty.tuple [];
                                  Ty.path "alloc::alloc::Global"
                                ],
                              "is_empty",
                              []
                            |),
                            [ full_borrows ]
                          |)
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_has_full_borrows :
        M.IsAssociatedFunction Self "has_full_borrows" has_full_borrows.
      
      (*
          fn has_consistent_borrows(&self, id: RefID, label_opt: Option<Label>) -> bool {
              let (full_borrows, field_borrows) = self.borrow_graph.borrowed_by(id);
              !full_borrows.is_empty() || {
                  match label_opt {
                      None => field_borrows.values().any(|borrows| !borrows.is_empty()),
                      Some(label) => field_borrows
                          .get(&label)
                          .map(|borrows| !borrows.is_empty())
                          .unwrap_or(false),
                  }
              }
          }
      *)
      Definition has_consistent_borrows (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; id; label_opt ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let id := M.alloc (| id |) in
            let label_opt := M.alloc (| label_opt |) in
            M.read (|
              M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      "borrowed_by",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |);
                      M.read (| id |)
                    ]
                  |)
                |),
                [
                  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 full_borrows := M.copy (| γ0_0 |) in
                      let field_borrows := M.copy (| γ0_1 |) in
                      M.alloc (|
                        LogicalOp.or (|
                          UnOp.not (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.apply
                                  (Ty.path "alloc::collections::btree::map::BTreeMap")
                                  []
                                  [
                                    Ty.path "move_borrow_graph::references::RefID";
                                    Ty.tuple [];
                                    Ty.path "alloc::alloc::Global"
                                  ],
                                "is_empty",
                                []
                              |),
                              [ full_borrows ]
                            |)
                          |),
                          ltac:(M.monadic
                            (M.read (|
                              M.match_operator (|
                                label_opt,
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let _ :=
                                        M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "alloc::collections::btree::map::Values")
                                              []
                                              [
                                                Ty.path
                                                  "move_bytecode_verifier::reference_safety::abstract_state::Label";
                                                Ty.apply
                                                  (Ty.path
                                                    "alloc::collections::btree::map::BTreeMap")
                                                  []
                                                  [
                                                    Ty.path "move_borrow_graph::references::RefID";
                                                    Ty.tuple [];
                                                    Ty.path "alloc::alloc::Global"
                                                  ]
                                              ],
                                            [],
                                            "any",
                                            [
                                              Ty.function
                                                [
                                                  Ty.tuple
                                                    [
                                                      Ty.apply
                                                        (Ty.path "&")
                                                        []
                                                        [
                                                          Ty.apply
                                                            (Ty.path
                                                              "alloc::collections::btree::map::BTreeMap")
                                                            []
                                                            [
                                                              Ty.path
                                                                "move_borrow_graph::references::RefID";
                                                              Ty.tuple [];
                                                              Ty.path "alloc::alloc::Global"
                                                            ]
                                                        ]
                                                    ]
                                                ]
                                                (Ty.path "bool")
                                            ]
                                          |),
                                          [
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.apply
                                                    (Ty.path
                                                      "alloc::collections::btree::map::BTreeMap")
                                                    []
                                                    [
                                                      Ty.path
                                                        "move_bytecode_verifier::reference_safety::abstract_state::Label";
                                                      Ty.apply
                                                        (Ty.path
                                                          "alloc::collections::btree::map::BTreeMap")
                                                        []
                                                        [
                                                          Ty.path
                                                            "move_borrow_graph::references::RefID";
                                                          Ty.tuple [];
                                                          Ty.path "alloc::alloc::Global"
                                                        ];
                                                      Ty.path "alloc::alloc::Global"
                                                    ],
                                                  "values",
                                                  []
                                                |),
                                                [ field_borrows ]
                                              |)
                                            |);
                                            M.closure
                                              (fun γ =>
                                                ltac:(M.monadic
                                                  match γ with
                                                  | [ α0 ] =>
                                                    ltac:(M.monadic
                                                      (M.match_operator (|
                                                        M.alloc (| α0 |),
                                                        [
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (let borrows := M.copy (| γ |) in
                                                              UnOp.not (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.apply
                                                                      (Ty.path
                                                                        "alloc::collections::btree::map::BTreeMap")
                                                                      []
                                                                      [
                                                                        Ty.path
                                                                          "move_borrow_graph::references::RefID";
                                                                        Ty.tuple [];
                                                                        Ty.path
                                                                          "alloc::alloc::Global"
                                                                      ],
                                                                    "is_empty",
                                                                    []
                                                                  |),
                                                                  [ M.read (| borrows |) ]
                                                                |)
                                                              |)))
                                                        ]
                                                      |)))
                                                  | _ => M.impossible "wrong number of arguments"
                                                  end))
                                          ]
                                        |)
                                      |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ0_0 :=
                                        M.SubPointer.get_struct_tuple_field (|
                                          γ,
                                          "core::option::Option::Some",
                                          0
                                        |) in
                                      let label := M.copy (| γ0_0 |) in
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.apply
                                              (Ty.path "core::option::Option")
                                              []
                                              [ Ty.path "bool" ],
                                            "unwrap_or",
                                            []
                                          |),
                                          [
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply
                                                  (Ty.path "core::option::Option")
                                                  []
                                                  [
                                                    Ty.apply
                                                      (Ty.path "&")
                                                      []
                                                      [
                                                        Ty.apply
                                                          (Ty.path
                                                            "alloc::collections::btree::map::BTreeMap")
                                                          []
                                                          [
                                                            Ty.path
                                                              "move_borrow_graph::references::RefID";
                                                            Ty.tuple [];
                                                            Ty.path "alloc::alloc::Global"
                                                          ]
                                                      ]
                                                  ],
                                                "map",
                                                [
                                                  Ty.path "bool";
                                                  Ty.function
                                                    [
                                                      Ty.tuple
                                                        [
                                                          Ty.apply
                                                            (Ty.path "&")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path
                                                                  "alloc::collections::btree::map::BTreeMap")
                                                                []
                                                                [
                                                                  Ty.path
                                                                    "move_borrow_graph::references::RefID";
                                                                  Ty.tuple [];
                                                                  Ty.path "alloc::alloc::Global"
                                                                ]
                                                            ]
                                                        ]
                                                    ]
                                                    (Ty.path "bool")
                                                ]
                                              |),
                                              [
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path
                                                        "alloc::collections::btree::map::BTreeMap")
                                                      []
                                                      [
                                                        Ty.path
                                                          "move_bytecode_verifier::reference_safety::abstract_state::Label";
                                                        Ty.apply
                                                          (Ty.path
                                                            "alloc::collections::btree::map::BTreeMap")
                                                          []
                                                          [
                                                            Ty.path
                                                              "move_borrow_graph::references::RefID";
                                                            Ty.tuple [];
                                                            Ty.path "alloc::alloc::Global"
                                                          ];
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "get",
                                                    [
                                                      Ty.path
                                                        "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                                    ]
                                                  |),
                                                  [ field_borrows; label ]
                                                |);
                                                M.closure
                                                  (fun γ =>
                                                    ltac:(M.monadic
                                                      match γ with
                                                      | [ α0 ] =>
                                                        ltac:(M.monadic
                                                          (M.match_operator (|
                                                            M.alloc (| α0 |),
                                                            [
                                                              fun γ =>
                                                                ltac:(M.monadic
                                                                  (let borrows := M.copy (| γ |) in
                                                                  UnOp.not (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.apply
                                                                          (Ty.path
                                                                            "alloc::collections::btree::map::BTreeMap")
                                                                          []
                                                                          [
                                                                            Ty.path
                                                                              "move_borrow_graph::references::RefID";
                                                                            Ty.tuple [];
                                                                            Ty.path
                                                                              "alloc::alloc::Global"
                                                                          ],
                                                                        "is_empty",
                                                                        []
                                                                      |),
                                                                      [ M.read (| borrows |) ]
                                                                    |)
                                                                  |)))
                                                            ]
                                                          |)))
                                                      | _ =>
                                                        M.impossible "wrong number of arguments"
                                                      end))
                                              ]
                                            |);
                                            Value.Bool false
                                          ]
                                        |)
                                      |)))
                                ]
                              |)
                            |)))
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_has_consistent_borrows :
        M.IsAssociatedFunction Self "has_consistent_borrows" has_consistent_borrows.
      
      (*
          fn has_consistent_mutable_borrows(&self, id: RefID, label_opt: Option<Label>) -> bool {
              let (full_borrows, field_borrows) = self.borrow_graph.borrowed_by(id);
              !self.all_immutable(&full_borrows) || {
                  match label_opt {
                      None => field_borrows
                          .values()
                          .any(|borrows| !self.all_immutable(borrows)),
                      Some(label) => field_borrows
                          .get(&label)
                          .map(|borrows| !self.all_immutable(borrows))
                          .unwrap_or(false),
                  }
              }
          }
      *)
      Definition has_consistent_mutable_borrows
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self; id; label_opt ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let id := M.alloc (| id |) in
            let label_opt := M.alloc (| label_opt |) in
            M.read (|
              M.match_operator (|
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      "borrowed_by",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |);
                      M.read (| id |)
                    ]
                  |)
                |),
                [
                  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 full_borrows := M.copy (| γ0_0 |) in
                      let field_borrows := M.copy (| γ0_1 |) in
                      M.alloc (|
                        LogicalOp.or (|
                          UnOp.not (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                "all_immutable",
                                []
                              |),
                              [ M.read (| self |); full_borrows ]
                            |)
                          |),
                          ltac:(M.monadic
                            (M.read (|
                              M.match_operator (|
                                label_opt,
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let _ :=
                                        M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "alloc::collections::btree::map::Values")
                                              []
                                              [
                                                Ty.path
                                                  "move_bytecode_verifier::reference_safety::abstract_state::Label";
                                                Ty.apply
                                                  (Ty.path
                                                    "alloc::collections::btree::map::BTreeMap")
                                                  []
                                                  [
                                                    Ty.path "move_borrow_graph::references::RefID";
                                                    Ty.tuple [];
                                                    Ty.path "alloc::alloc::Global"
                                                  ]
                                              ],
                                            [],
                                            "any",
                                            [
                                              Ty.function
                                                [
                                                  Ty.tuple
                                                    [
                                                      Ty.apply
                                                        (Ty.path "&")
                                                        []
                                                        [
                                                          Ty.apply
                                                            (Ty.path
                                                              "alloc::collections::btree::map::BTreeMap")
                                                            []
                                                            [
                                                              Ty.path
                                                                "move_borrow_graph::references::RefID";
                                                              Ty.tuple [];
                                                              Ty.path "alloc::alloc::Global"
                                                            ]
                                                        ]
                                                    ]
                                                ]
                                                (Ty.path "bool")
                                            ]
                                          |),
                                          [
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.apply
                                                    (Ty.path
                                                      "alloc::collections::btree::map::BTreeMap")
                                                    []
                                                    [
                                                      Ty.path
                                                        "move_bytecode_verifier::reference_safety::abstract_state::Label";
                                                      Ty.apply
                                                        (Ty.path
                                                          "alloc::collections::btree::map::BTreeMap")
                                                        []
                                                        [
                                                          Ty.path
                                                            "move_borrow_graph::references::RefID";
                                                          Ty.tuple [];
                                                          Ty.path "alloc::alloc::Global"
                                                        ];
                                                      Ty.path "alloc::alloc::Global"
                                                    ],
                                                  "values",
                                                  []
                                                |),
                                                [ field_borrows ]
                                              |)
                                            |);
                                            M.closure
                                              (fun γ =>
                                                ltac:(M.monadic
                                                  match γ with
                                                  | [ α0 ] =>
                                                    ltac:(M.monadic
                                                      (M.match_operator (|
                                                        M.alloc (| α0 |),
                                                        [
                                                          fun γ =>
                                                            ltac:(M.monadic
                                                              (let borrows := M.copy (| γ |) in
                                                              UnOp.not (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path
                                                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                    "all_immutable",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.read (| self |);
                                                                    M.read (| borrows |)
                                                                  ]
                                                                |)
                                                              |)))
                                                        ]
                                                      |)))
                                                  | _ => M.impossible "wrong number of arguments"
                                                  end))
                                          ]
                                        |)
                                      |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ0_0 :=
                                        M.SubPointer.get_struct_tuple_field (|
                                          γ,
                                          "core::option::Option::Some",
                                          0
                                        |) in
                                      let label := M.copy (| γ0_0 |) in
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.apply
                                              (Ty.path "core::option::Option")
                                              []
                                              [ Ty.path "bool" ],
                                            "unwrap_or",
                                            []
                                          |),
                                          [
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.apply
                                                  (Ty.path "core::option::Option")
                                                  []
                                                  [
                                                    Ty.apply
                                                      (Ty.path "&")
                                                      []
                                                      [
                                                        Ty.apply
                                                          (Ty.path
                                                            "alloc::collections::btree::map::BTreeMap")
                                                          []
                                                          [
                                                            Ty.path
                                                              "move_borrow_graph::references::RefID";
                                                            Ty.tuple [];
                                                            Ty.path "alloc::alloc::Global"
                                                          ]
                                                      ]
                                                  ],
                                                "map",
                                                [
                                                  Ty.path "bool";
                                                  Ty.function
                                                    [
                                                      Ty.tuple
                                                        [
                                                          Ty.apply
                                                            (Ty.path "&")
                                                            []
                                                            [
                                                              Ty.apply
                                                                (Ty.path
                                                                  "alloc::collections::btree::map::BTreeMap")
                                                                []
                                                                [
                                                                  Ty.path
                                                                    "move_borrow_graph::references::RefID";
                                                                  Ty.tuple [];
                                                                  Ty.path "alloc::alloc::Global"
                                                                ]
                                                            ]
                                                        ]
                                                    ]
                                                    (Ty.path "bool")
                                                ]
                                              |),
                                              [
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path
                                                        "alloc::collections::btree::map::BTreeMap")
                                                      []
                                                      [
                                                        Ty.path
                                                          "move_bytecode_verifier::reference_safety::abstract_state::Label";
                                                        Ty.apply
                                                          (Ty.path
                                                            "alloc::collections::btree::map::BTreeMap")
                                                          []
                                                          [
                                                            Ty.path
                                                              "move_borrow_graph::references::RefID";
                                                            Ty.tuple [];
                                                            Ty.path "alloc::alloc::Global"
                                                          ];
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "get",
                                                    [
                                                      Ty.path
                                                        "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                                    ]
                                                  |),
                                                  [ field_borrows; label ]
                                                |);
                                                M.closure
                                                  (fun γ =>
                                                    ltac:(M.monadic
                                                      match γ with
                                                      | [ α0 ] =>
                                                        ltac:(M.monadic
                                                          (M.match_operator (|
                                                            M.alloc (| α0 |),
                                                            [
                                                              fun γ =>
                                                                ltac:(M.monadic
                                                                  (let borrows := M.copy (| γ |) in
                                                                  UnOp.not (|
                                                                    M.call_closure (|
                                                                      M.get_associated_function (|
                                                                        Ty.path
                                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                        "all_immutable",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.read (| self |);
                                                                        M.read (| borrows |)
                                                                      ]
                                                                    |)
                                                                  |)))
                                                            ]
                                                          |)))
                                                      | _ =>
                                                        M.impossible "wrong number of arguments"
                                                      end))
                                              ]
                                            |);
                                            Value.Bool false
                                          ]
                                        |)
                                      |)))
                                ]
                              |)
                            |)))
                        |)
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_has_consistent_mutable_borrows :
        M.IsAssociatedFunction Self "has_consistent_mutable_borrows" has_consistent_mutable_borrows.
      
      (*
          fn is_writable(&self, id: RefID) -> bool {
              assert!(self.borrow_graph.is_mutable(id));
              !self.has_consistent_borrows(id, None)
          }
      *)
      Definition is_writable (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; id ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let id := M.alloc (| id |) in
            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.apply
                                      (Ty.path "move_borrow_graph::graph::BorrowGraph")
                                      []
                                      [
                                        Ty.tuple [];
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                      ],
                                    "is_mutable",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                      "borrow_graph"
                                    |);
                                    M.read (| id |)
                                  ]
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.never_to_any (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic", [] |),
                              [
                                M.read (|
                                  Value.String "assertion failed: self.borrow_graph.is_mutable(id)"
                                |)
                              ]
                            |)
                          |)
                        |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |) in
              M.alloc (|
                UnOp.not (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                      "has_consistent_borrows",
                      []
                    |),
                    [
                      M.read (| self |);
                      M.read (| id |);
                      Value.StructTuple "core::option::Option::None" []
                    ]
                  |)
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_writable : M.IsAssociatedFunction Self "is_writable" is_writable.
      
      (*
          fn is_freezable(&self, id: RefID, at_field_opt: Option<FieldHandleIndex>) -> bool {
              assert!(self.borrow_graph.is_mutable(id));
              !self.has_consistent_mutable_borrows(id, at_field_opt.map(Label::Field))
          }
      *)
      Definition is_freezable (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; id; at_field_opt ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let id := M.alloc (| id |) in
            let at_field_opt := M.alloc (| at_field_opt |) in
            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.apply
                                      (Ty.path "move_borrow_graph::graph::BorrowGraph")
                                      []
                                      [
                                        Ty.tuple [];
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                      ],
                                    "is_mutable",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                      "borrow_graph"
                                    |);
                                    M.read (| id |)
                                  ]
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.never_to_any (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic", [] |),
                              [
                                M.read (|
                                  Value.String "assertion failed: self.borrow_graph.is_mutable(id)"
                                |)
                              ]
                            |)
                          |)
                        |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |) in
              M.alloc (|
                UnOp.not (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                      "has_consistent_mutable_borrows",
                      []
                    |),
                    [
                      M.read (| self |);
                      M.read (| id |);
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "core::option::Option")
                            []
                            [ Ty.path "move_binary_format::file_format::FieldHandleIndex" ],
                          "map",
                          [
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::Label";
                            Ty.function
                              [ Ty.path "move_binary_format::file_format::FieldHandleIndex" ]
                              (Ty.path
                                "move_bytecode_verifier::reference_safety::abstract_state::Label")
                          ]
                        |),
                        [
                          M.read (| at_field_opt |);
                          M.constructor_as_closure
                            "move_bytecode_verifier::reference_safety::abstract_state::Label::Field"
                        ]
                      |)
                    ]
                  |)
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_freezable :
        M.IsAssociatedFunction Self "is_freezable" is_freezable.
      
      (*
          fn is_readable(&self, id: RefID, at_field_opt: Option<FieldHandleIndex>) -> bool {
              let is_mutable = self.borrow_graph.is_mutable(id);
              !is_mutable || self.is_freezable(id, at_field_opt)
          }
      *)
      Definition is_readable (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; id; at_field_opt ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let id := M.alloc (| id |) in
            let at_field_opt := M.alloc (| at_field_opt |) in
            M.read (|
              let~ is_mutable :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      "is_mutable",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |);
                      M.read (| id |)
                    ]
                  |)
                |) in
              M.alloc (|
                LogicalOp.or (|
                  UnOp.not (| M.read (| is_mutable |) |),
                  ltac:(M.monadic
                    (M.call_closure (|
                      M.get_associated_function (|
                        Ty.path
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "is_freezable",
                        []
                      |),
                      [ M.read (| self |); M.read (| id |); M.read (| at_field_opt |) ]
                    |)))
                |)
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_readable : M.IsAssociatedFunction Self "is_readable" is_readable.
      
      (*
          fn is_local_borrowed(&self, idx: LocalIndex) -> bool {
              self.has_consistent_borrows(self.frame_root(), Some(Label::Local(idx)))
          }
      *)
      Definition is_local_borrowed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; idx ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let idx := M.alloc (| idx |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                "has_consistent_borrows",
                []
              |),
              [
                M.read (| self |);
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "frame_root",
                    []
                  |),
                  [ M.read (| self |) ]
                |);
                Value.StructTuple
                  "core::option::Option::Some"
                  [
                    Value.StructTuple
                      "move_bytecode_verifier::reference_safety::abstract_state::Label::Local"
                      [ M.read (| idx |) ]
                  ]
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_local_borrowed :
        M.IsAssociatedFunction Self "is_local_borrowed" is_local_borrowed.
      
      (*
          fn is_local_mutably_borrowed(&self, idx: LocalIndex) -> bool {
              self.has_consistent_mutable_borrows(self.frame_root(), Some(Label::Local(idx)))
          }
      *)
      Definition is_local_mutably_borrowed
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self; idx ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let idx := M.alloc (| idx |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                "has_consistent_mutable_borrows",
                []
              |),
              [
                M.read (| self |);
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "frame_root",
                    []
                  |),
                  [ M.read (| self |) ]
                |);
                Value.StructTuple
                  "core::option::Option::Some"
                  [
                    Value.StructTuple
                      "move_bytecode_verifier::reference_safety::abstract_state::Label::Local"
                      [ M.read (| idx |) ]
                  ]
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_local_mutably_borrowed :
        M.IsAssociatedFunction Self "is_local_mutably_borrowed" is_local_mutably_borrowed.
      
      (*
          fn is_global_borrowed(&self, resource: StructDefinitionIndex) -> bool {
              self.has_consistent_borrows(self.frame_root(), Some(Label::Global(resource)))
          }
      *)
      Definition is_global_borrowed (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; resource ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let resource := M.alloc (| resource |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                "has_consistent_borrows",
                []
              |),
              [
                M.read (| self |);
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "frame_root",
                    []
                  |),
                  [ M.read (| self |) ]
                |);
                Value.StructTuple
                  "core::option::Option::Some"
                  [
                    Value.StructTuple
                      "move_bytecode_verifier::reference_safety::abstract_state::Label::Global"
                      [ M.read (| resource |) ]
                  ]
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_global_borrowed :
        M.IsAssociatedFunction Self "is_global_borrowed" is_global_borrowed.
      
      (*
          fn is_global_mutably_borrowed(&self, resource: StructDefinitionIndex) -> bool {
              self.has_consistent_mutable_borrows(self.frame_root(), Some(Label::Global(resource)))
          }
      *)
      Definition is_global_mutably_borrowed
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self; resource ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let resource := M.alloc (| resource |) in
            M.call_closure (|
              M.get_associated_function (|
                Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                "has_consistent_mutable_borrows",
                []
              |),
              [
                M.read (| self |);
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.path
                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "frame_root",
                    []
                  |),
                  [ M.read (| self |) ]
                |);
                Value.StructTuple
                  "core::option::Option::Some"
                  [
                    Value.StructTuple
                      "move_bytecode_verifier::reference_safety::abstract_state::Label::Global"
                      [ M.read (| resource |) ]
                  ]
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_global_mutably_borrowed :
        M.IsAssociatedFunction Self "is_global_mutably_borrowed" is_global_mutably_borrowed.
      
      (*
          fn is_frame_safe_to_destroy(&self) -> bool {
              !self.has_consistent_borrows(self.frame_root(), None)
          }
      *)
      Definition is_frame_safe_to_destroy
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            UnOp.not (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                  "has_consistent_borrows",
                  []
                |),
                [
                  M.read (| self |);
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.path
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                      "frame_root",
                      []
                    |),
                    [ M.read (| self |) ]
                  |);
                  Value.StructTuple "core::option::Option::None" []
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_frame_safe_to_destroy :
        M.IsAssociatedFunction Self "is_frame_safe_to_destroy" is_frame_safe_to_destroy.
      
      (*
          pub fn release_value(&mut self, value: AbstractValue) {
              match value {
                  AbstractValue::Reference(id) => self.release(id),
                  AbstractValue::NonReference => (),
              }
          }
      *)
      Definition release_value (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; value ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let value := M.alloc (| value |) in
            M.read (|
              M.match_operator (|
                value,
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ0_0 :=
                        M.SubPointer.get_struct_tuple_field (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                          0
                        |) in
                      let id := M.copy (| γ0_0 |) in
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                            "release",
                            []
                          |),
                          [ M.read (| self |); M.read (| id |) ]
                        |)
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (let _ :=
                        M.is_struct_tuple (|
                          γ,
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                        |) in
                      M.alloc (| Value.Tuple [] |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_release_value :
        M.IsAssociatedFunction Self "release_value" release_value.
      
      (*
          pub fn copy_loc(
              &mut self,
              offset: CodeOffset,
              local: LocalIndex,
          ) -> PartialVMResult<AbstractValue> {
              match safe_unwrap!(self.locals.get(local as usize)) {
                  AbstractValue::Reference(id) => {
                      let id = *id;
                      let new_id = self.new_ref(self.borrow_graph.is_mutable(id));
                      self.add_copy(id, new_id);
                      Ok(AbstractValue::Reference(new_id))
                  }
                  AbstractValue::NonReference if self.is_local_mutably_borrowed(local) => {
                      Err(self.error(StatusCode::COPYLOC_EXISTS_BORROW_ERROR, offset))
                  }
                  AbstractValue::NonReference => Ok(AbstractValue::NonReference),
              }
          }
      *)
      Definition copy_loc (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; local ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let local := M.alloc (| local |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  M.match_operator (|
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.apply
                              (Ty.path "slice")
                              []
                              [
                                Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                              ],
                            "get",
                            [ Ty.path "usize" ]
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::ops::deref::Deref",
                                Ty.apply
                                  (Ty.path "alloc::vec::Vec")
                                  []
                                  [
                                    Ty.path
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                    Ty.path "alloc::alloc::Global"
                                  ],
                                [],
                                "deref",
                                []
                              |),
                              [
                                M.SubPointer.get_struct_record_field (|
                                  M.read (| self |),
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                  "locals"
                                |)
                              ]
                            |);
                            M.rust_cast (M.read (| local |))
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::option::Option::Some",
                                0
                              |) in
                            let x := M.copy (| γ0_0 |) in
                            x));
                        fun γ =>
                          ltac:(M.monadic
                            (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                            let~ err :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "move_binary_format::errors::PartialVMError",
                                    "with_message",
                                    []
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path "move_binary_format::errors::PartialVMError",
                                        "new",
                                        []
                                      |),
                                      [
                                        Value.StructTuple
                                          "move_core_types::vm_status::StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR"
                                          []
                                      ]
                                    |);
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::hint::must_use",
                                        [ Ty.path "alloc::string::String" ]
                                      |),
                                      [
                                        M.read (|
                                          let~ res :=
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_function (| "alloc::fmt::format", [] |),
                                                [
                                                  M.call_closure (|
                                                    M.get_associated_function (|
                                                      Ty.path "core::fmt::Arguments",
                                                      "new_v1",
                                                      []
                                                    |),
                                                    [
                                                      M.alloc (|
                                                        Value.Array
                                                          [
                                                            M.read (|
                                                              Value.String
                                                                "crates/move-bytecode-verifier/src/reference_safety/abstract_state.rs:305 (none)"
                                                            |)
                                                          ]
                                                      |);
                                                      M.alloc (|
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path "core::fmt::rt::Argument",
                                                            "none",
                                                            []
                                                          |),
                                                          []
                                                        |)
                                                      |)
                                                    ]
                                                  |)
                                                ]
                                              |)
                                            |) in
                                          res
                                        |)
                                      ]
                                    |)
                                  ]
                                |)
                              |) in
                            M.match_operator (|
                              M.alloc (| Value.Tuple [] |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ := M.use (M.alloc (| Value.Bool true |)) in
                                    let _ :=
                                      M.is_constant_or_break_match (|
                                        M.read (| γ |),
                                        Value.Bool true
                                      |) in
                                    M.alloc (|
                                      M.never_to_any (|
                                        M.call_closure (|
                                          M.get_function (| "core::panicking::panic_fmt", [] |),
                                          [
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path "core::fmt::Arguments",
                                                "new_v1",
                                                []
                                              |),
                                              [
                                                M.alloc (|
                                                  Value.Array [ M.read (| Value.String "" |) ]
                                                |);
                                                M.alloc (|
                                                  Value.Array
                                                    [
                                                      M.call_closure (|
                                                        M.get_associated_function (|
                                                          Ty.path "core::fmt::rt::Argument",
                                                          "new_debug",
                                                          [
                                                            Ty.path
                                                              "move_binary_format::errors::PartialVMError"
                                                          ]
                                                        |),
                                                        [ err ]
                                                      |)
                                                    ]
                                                |)
                                              ]
                                            |)
                                          ]
                                        |)
                                      |)
                                    |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (M.alloc (|
                                      M.never_to_any (|
                                        M.read (|
                                          M.return_ (|
                                            Value.StructTuple
                                              "core::result::Result::Err"
                                              [ M.read (| err |) ]
                                          |)
                                        |)
                                      |)
                                    |)))
                              ]
                            |)))
                      ]
                    |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let γ1_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                              0
                            |) in
                          let id := M.alloc (| γ1_0 |) in
                          let~ id := M.copy (| M.read (| id |) |) in
                          let~ new_id :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                  "new_ref",
                                  []
                                |),
                                [
                                  M.read (| self |);
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                                        []
                                        [
                                          Ty.tuple [];
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                        ],
                                      "is_mutable",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "borrow_graph"
                                      |);
                                      M.read (| id |)
                                    ]
                                  |)
                                ]
                              |)
                            |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                  "add_copy",
                                  []
                                |),
                                [ M.read (| self |); M.read (| id |); M.read (| new_id |) ]
                              |)
                            |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Ok"
                              [
                                Value.StructTuple
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                                  [ M.read (| new_id |) ]
                              ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let _ :=
                            M.is_struct_tuple (|
                              γ,
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                            |) in
                          let γ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                  "is_local_mutably_borrowed",
                                  []
                                |),
                                [ M.read (| self |); M.read (| local |) ]
                              |)
                            |) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Err"
                              [
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                    "error",
                                    []
                                  |),
                                  [
                                    M.read (| self |);
                                    Value.StructTuple
                                      "move_core_types::vm_status::StatusCode::COPYLOC_EXISTS_BORROW_ERROR"
                                      [];
                                    M.read (| offset |)
                                  ]
                                |)
                              ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let γ := M.read (| γ |) in
                          let _ :=
                            M.is_struct_tuple (|
                              γ,
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                            |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Ok"
                              [
                                Value.StructTuple
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                                  []
                              ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_copy_loc : M.IsAssociatedFunction Self "copy_loc" copy_loc.
      
      (*
          pub fn move_loc(
              &mut self,
              offset: CodeOffset,
              local: LocalIndex,
          ) -> PartialVMResult<AbstractValue> {
              let old_value = std::mem::replace(
                  safe_unwrap!(self.locals.get_mut(local as usize)),
                  AbstractValue::NonReference,
              );
              match old_value {
                  AbstractValue::Reference(id) => Ok(AbstractValue::Reference(id)),
                  AbstractValue::NonReference if self.is_local_borrowed(local) => {
                      Err(self.error(StatusCode::MOVELOC_EXISTS_BORROW_ERROR, offset))
                  }
                  AbstractValue::NonReference => Ok(AbstractValue::NonReference),
              }
          }
      *)
      Definition move_loc (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; local ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let local := M.alloc (| local |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ old_value :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_function (|
                          "core::mem::replace",
                          [
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                          ]
                        |),
                        [
                          M.read (|
                            M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply
                                      (Ty.path "slice")
                                      []
                                      [
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                      ],
                                    "get_mut",
                                    [ Ty.path "usize" ]
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::deref::DerefMut",
                                        Ty.apply
                                          (Ty.path "alloc::vec::Vec")
                                          []
                                          [
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                            Ty.path "alloc::alloc::Global"
                                          ],
                                        [],
                                        "deref_mut",
                                        []
                                      |),
                                      [
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                          "locals"
                                        |)
                                      ]
                                    |);
                                    M.rust_cast (M.read (| local |))
                                  ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::option::Option::Some",
                                        0
                                      |) in
                                    let x := M.copy (| γ0_0 |) in
                                    M.alloc (| M.read (| x |) |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (let _ :=
                                      M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                    let~ err :=
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "move_binary_format::errors::PartialVMError",
                                            "with_message",
                                            []
                                          |),
                                          [
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path
                                                  "move_binary_format::errors::PartialVMError",
                                                "new",
                                                []
                                              |),
                                              [
                                                Value.StructTuple
                                                  "move_core_types::vm_status::StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR"
                                                  []
                                              ]
                                            |);
                                            M.call_closure (|
                                              M.get_function (|
                                                "core::hint::must_use",
                                                [ Ty.path "alloc::string::String" ]
                                              |),
                                              [
                                                M.read (|
                                                  let~ res :=
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_function (|
                                                          "alloc::fmt::format",
                                                          []
                                                        |),
                                                        [
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path "core::fmt::Arguments",
                                                              "new_v1",
                                                              []
                                                            |),
                                                            [
                                                              M.alloc (|
                                                                Value.Array
                                                                  [
                                                                    M.read (|
                                                                      Value.String
                                                                        "crates/move-bytecode-verifier/src/reference_safety/abstract_state.rs:325 (none)"
                                                                    |)
                                                                  ]
                                                              |);
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path
                                                                      "core::fmt::rt::Argument",
                                                                    "none",
                                                                    []
                                                                  |),
                                                                  []
                                                                |)
                                                              |)
                                                            ]
                                                          |)
                                                        ]
                                                      |)
                                                    |) in
                                                  res
                                                |)
                                              ]
                                            |)
                                          ]
                                        |)
                                      |) in
                                    M.alloc (|
                                      M.read (|
                                        M.match_operator (|
                                          M.alloc (| Value.Tuple [] |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ := M.use (M.alloc (| Value.Bool true |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                M.alloc (|
                                                  M.never_to_any (|
                                                    M.call_closure (|
                                                      M.get_function (|
                                                        "core::panicking::panic_fmt",
                                                        []
                                                      |),
                                                      [
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path "core::fmt::Arguments",
                                                            "new_v1",
                                                            []
                                                          |),
                                                          [
                                                            M.alloc (|
                                                              Value.Array
                                                                [ M.read (| Value.String "" |) ]
                                                            |);
                                                            M.alloc (|
                                                              Value.Array
                                                                [
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path
                                                                        "core::fmt::rt::Argument",
                                                                      "new_debug",
                                                                      [
                                                                        Ty.path
                                                                          "move_binary_format::errors::PartialVMError"
                                                                      ]
                                                                    |),
                                                                    [ err ]
                                                                  |)
                                                                ]
                                                            |)
                                                          ]
                                                        |)
                                                      ]
                                                    |)
                                                  |)
                                                |)));
                                            fun γ =>
                                              ltac:(M.monadic
                                                (M.alloc (|
                                                  M.never_to_any (|
                                                    M.read (|
                                                      M.return_ (|
                                                        Value.StructTuple
                                                          "core::result::Result::Err"
                                                          [ M.read (| err |) ]
                                                      |)
                                                    |)
                                                  |)
                                                |)))
                                          ]
                                        |)
                                      |)
                                    |)))
                              ]
                            |)
                          |);
                          Value.StructTuple
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                            []
                        ]
                      |)
                    |) in
                  M.match_operator (|
                    old_value,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                              0
                            |) in
                          let id := M.copy (| γ0_0 |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Ok"
                              [
                                Value.StructTuple
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                                  [ M.read (| id |) ]
                              ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ :=
                            M.is_struct_tuple (|
                              γ,
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                            |) in
                          let γ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                  "is_local_borrowed",
                                  []
                                |),
                                [ M.read (| self |); M.read (| local |) ]
                              |)
                            |) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Err"
                              [
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                    "error",
                                    []
                                  |),
                                  [
                                    M.read (| self |);
                                    Value.StructTuple
                                      "move_core_types::vm_status::StatusCode::MOVELOC_EXISTS_BORROW_ERROR"
                                      [];
                                    M.read (| offset |)
                                  ]
                                |)
                              ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ :=
                            M.is_struct_tuple (|
                              γ,
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                            |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Ok"
                              [
                                Value.StructTuple
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                                  []
                              ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_move_loc : M.IsAssociatedFunction Self "move_loc" move_loc.
      
      (*
          pub fn st_loc(
              &mut self,
              offset: CodeOffset,
              local: LocalIndex,
              new_value: AbstractValue,
          ) -> PartialVMResult<()> {
              let old_value =
                  std::mem::replace(safe_unwrap!(self.locals.get_mut(local as usize)), new_value);
              match old_value {
                  AbstractValue::Reference(id) => {
                      self.release(id);
                      Ok(())
                  }
                  AbstractValue::NonReference if self.is_local_borrowed(local) => {
                      Err(self.error(StatusCode::STLOC_UNSAFE_TO_DESTROY_ERROR, offset))
                  }
                  AbstractValue::NonReference => Ok(()),
              }
          }
      *)
      Definition st_loc (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; local; new_value ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let local := M.alloc (| local |) in
            let new_value := M.alloc (| new_value |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ old_value :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_function (|
                          "core::mem::replace",
                          [
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                          ]
                        |),
                        [
                          M.read (|
                            M.match_operator (|
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply
                                      (Ty.path "slice")
                                      []
                                      [
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                      ],
                                    "get_mut",
                                    [ Ty.path "usize" ]
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::deref::DerefMut",
                                        Ty.apply
                                          (Ty.path "alloc::vec::Vec")
                                          []
                                          [
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                            Ty.path "alloc::alloc::Global"
                                          ],
                                        [],
                                        "deref_mut",
                                        []
                                      |),
                                      [
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                          "locals"
                                        |)
                                      ]
                                    |);
                                    M.rust_cast (M.read (| local |))
                                  ]
                                |)
                              |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let γ0_0 :=
                                      M.SubPointer.get_struct_tuple_field (|
                                        γ,
                                        "core::option::Option::Some",
                                        0
                                      |) in
                                    let x := M.copy (| γ0_0 |) in
                                    M.alloc (| M.read (| x |) |)));
                                fun γ =>
                                  ltac:(M.monadic
                                    (let _ :=
                                      M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                                    let~ err :=
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path "move_binary_format::errors::PartialVMError",
                                            "with_message",
                                            []
                                          |),
                                          [
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path
                                                  "move_binary_format::errors::PartialVMError",
                                                "new",
                                                []
                                              |),
                                              [
                                                Value.StructTuple
                                                  "move_core_types::vm_status::StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR"
                                                  []
                                              ]
                                            |);
                                            M.call_closure (|
                                              M.get_function (|
                                                "core::hint::must_use",
                                                [ Ty.path "alloc::string::String" ]
                                              |),
                                              [
                                                M.read (|
                                                  let~ res :=
                                                    M.alloc (|
                                                      M.call_closure (|
                                                        M.get_function (|
                                                          "alloc::fmt::format",
                                                          []
                                                        |),
                                                        [
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path "core::fmt::Arguments",
                                                              "new_v1",
                                                              []
                                                            |),
                                                            [
                                                              M.alloc (|
                                                                Value.Array
                                                                  [
                                                                    M.read (|
                                                                      Value.String
                                                                        "crates/move-bytecode-verifier/src/reference_safety/abstract_state.rs:344 (none)"
                                                                    |)
                                                                  ]
                                                              |);
                                                              M.alloc (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path
                                                                      "core::fmt::rt::Argument",
                                                                    "none",
                                                                    []
                                                                  |),
                                                                  []
                                                                |)
                                                              |)
                                                            ]
                                                          |)
                                                        ]
                                                      |)
                                                    |) in
                                                  res
                                                |)
                                              ]
                                            |)
                                          ]
                                        |)
                                      |) in
                                    M.alloc (|
                                      M.read (|
                                        M.match_operator (|
                                          M.alloc (| Value.Tuple [] |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let γ := M.use (M.alloc (| Value.Bool true |)) in
                                                let _ :=
                                                  M.is_constant_or_break_match (|
                                                    M.read (| γ |),
                                                    Value.Bool true
                                                  |) in
                                                M.alloc (|
                                                  M.never_to_any (|
                                                    M.call_closure (|
                                                      M.get_function (|
                                                        "core::panicking::panic_fmt",
                                                        []
                                                      |),
                                                      [
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path "core::fmt::Arguments",
                                                            "new_v1",
                                                            []
                                                          |),
                                                          [
                                                            M.alloc (|
                                                              Value.Array
                                                                [ M.read (| Value.String "" |) ]
                                                            |);
                                                            M.alloc (|
                                                              Value.Array
                                                                [
                                                                  M.call_closure (|
                                                                    M.get_associated_function (|
                                                                      Ty.path
                                                                        "core::fmt::rt::Argument",
                                                                      "new_debug",
                                                                      [
                                                                        Ty.path
                                                                          "move_binary_format::errors::PartialVMError"
                                                                      ]
                                                                    |),
                                                                    [ err ]
                                                                  |)
                                                                ]
                                                            |)
                                                          ]
                                                        |)
                                                      ]
                                                    |)
                                                  |)
                                                |)));
                                            fun γ =>
                                              ltac:(M.monadic
                                                (M.alloc (|
                                                  M.never_to_any (|
                                                    M.read (|
                                                      M.return_ (|
                                                        Value.StructTuple
                                                          "core::result::Result::Err"
                                                          [ M.read (| err |) ]
                                                      |)
                                                    |)
                                                  |)
                                                |)))
                                          ]
                                        |)
                                      |)
                                    |)))
                              ]
                            |)
                          |);
                          M.read (| new_value |)
                        ]
                      |)
                    |) in
                  M.match_operator (|
                    old_value,
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ0_0 :=
                            M.SubPointer.get_struct_tuple_field (|
                              γ,
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                              0
                            |) in
                          let id := M.copy (| γ0_0 |) in
                          let~ _ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                  "release",
                                  []
                                |),
                                [ M.read (| self |); M.read (| id |) ]
                              |)
                            |) in
                          M.alloc (|
                            Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ :=
                            M.is_struct_tuple (|
                              γ,
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                            |) in
                          let γ :=
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                  "is_local_borrowed",
                                  []
                                |),
                                [ M.read (| self |); M.read (| local |) ]
                              |)
                            |) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Err"
                              [
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                    "error",
                                    []
                                  |),
                                  [
                                    M.read (| self |);
                                    Value.StructTuple
                                      "move_core_types::vm_status::StatusCode::STLOC_UNSAFE_TO_DESTROY_ERROR"
                                      [];
                                    M.read (| offset |)
                                  ]
                                |)
                              ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let _ :=
                            M.is_struct_tuple (|
                              γ,
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                            |) in
                          M.alloc (|
                            Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_st_loc : M.IsAssociatedFunction Self "st_loc" st_loc.
      
      (*
          pub fn freeze_ref(&mut self, offset: CodeOffset, id: RefID) -> PartialVMResult<AbstractValue> {
              if !self.is_freezable(id, None) {
                  return Err(self.error(StatusCode::FREEZEREF_EXISTS_MUTABLE_BORROW_ERROR, offset));
              }
      
              let frozen_id = self.new_ref(false);
              self.add_copy(id, frozen_id);
              self.release(id);
              Ok(AbstractValue::Reference(frozen_id))
          }
      *)
      Definition freeze_ref (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; id ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let id := M.alloc (| id |) 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
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "is_freezable",
                                        []
                                      |),
                                      [
                                        M.read (| self |);
                                        M.read (| id |);
                                        Value.StructTuple "core::option::Option::None" []
                                      ]
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::FREEZEREF_EXISTS_MUTABLE_BORROW_ERROR"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ frozen_id :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "new_ref",
                          []
                        |),
                        [ M.read (| self |); Value.Bool false ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "add_copy",
                          []
                        |),
                        [ M.read (| self |); M.read (| id |); M.read (| frozen_id |) ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "release",
                          []
                        |),
                        [ M.read (| self |); M.read (| id |) ]
                      |)
                    |) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                          [ M.read (| frozen_id |) ]
                      ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_freeze_ref : M.IsAssociatedFunction Self "freeze_ref" freeze_ref.
      
      (*
          pub fn comparison(
              &mut self,
              offset: CodeOffset,
              v1: AbstractValue,
              v2: AbstractValue,
          ) -> PartialVMResult<AbstractValue> {
              match (v1, v2) {
                  (AbstractValue::Reference(id1), AbstractValue::Reference(id2))
                      if !self.is_readable(id1, None) || !self.is_readable(id2, None) =>
                  {
                      // TODO better error code
                      return Err(self.error(StatusCode::READREF_EXISTS_MUTABLE_BORROW_ERROR, offset));
                  }
                  (AbstractValue::Reference(id1), AbstractValue::Reference(id2)) => {
                      self.release(id1);
                      self.release(id2)
                  }
                  (v1, v2) => {
                      assert!(v1.is_value());
                      assert!(v2.is_value());
                  }
              }
              Ok(AbstractValue::NonReference)
          }
      *)
      Definition comparison (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; v1; v2 ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let v1 := M.alloc (| v1 |) in
            let v2 := M.alloc (| v2 |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (| Value.Tuple [ M.read (| v1 |); M.read (| v2 |) ] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                            let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                            let γ1_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ0_0,
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                0
                              |) in
                            let id1 := M.copy (| γ1_0 |) in
                            let γ1_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ0_1,
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                0
                              |) in
                            let id2 := M.copy (| γ1_0 |) in
                            let γ :=
                              M.alloc (|
                                LogicalOp.or (|
                                  UnOp.not (|
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "is_readable",
                                        []
                                      |),
                                      [
                                        M.read (| self |);
                                        M.read (| id1 |);
                                        Value.StructTuple "core::option::Option::None" []
                                      ]
                                    |)
                                  |),
                                  ltac:(M.monadic
                                    (UnOp.not (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                          "is_readable",
                                          []
                                        |),
                                        [
                                          M.read (| self |);
                                          M.read (| id2 |);
                                          Value.StructTuple "core::option::Option::None" []
                                        ]
                                      |)
                                    |)))
                                |)
                              |) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::READREF_EXISTS_MUTABLE_BORROW_ERROR"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                            let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                            let γ1_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ0_0,
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                0
                              |) in
                            let id1 := M.copy (| γ1_0 |) in
                            let γ1_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ0_1,
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                0
                              |) in
                            let id2 := M.copy (| γ1_0 |) in
                            let~ _ :=
                              M.alloc (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                    "release",
                                    []
                                  |),
                                  [ M.read (| self |); M.read (| id1 |) ]
                                |)
                              |) in
                            M.alloc (|
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                  "release",
                                  []
                                |),
                                [ M.read (| self |); M.read (| id2 |) ]
                              |)
                            |)));
                        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 v1 := M.copy (| γ0_0 |) in
                            let v2 := M.copy (| γ0_1 |) 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
                                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue",
                                                  "is_value",
                                                  []
                                                |),
                                                [ v1 ]
                                              |)
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.call_closure (|
                                            M.get_function (| "core::panicking::panic", [] |),
                                            [
                                              M.read (|
                                                Value.String "assertion failed: v1.is_value()"
                                              |)
                                            ]
                                          |)
                                        |)
                                      |)));
                                  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
                                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue",
                                                  "is_value",
                                                  []
                                                |),
                                                [ v2 ]
                                              |)
                                            |)
                                          |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.call_closure (|
                                            M.get_function (| "core::panicking::panic", [] |),
                                            [
                                              M.read (|
                                                Value.String "assertion failed: v2.is_value()"
                                              |)
                                            ]
                                          |)
                                        |)
                                      |)));
                                  fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                ]
                              |) in
                            M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                          []
                      ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_comparison : M.IsAssociatedFunction Self "comparison" comparison.
      
      (*
          pub fn read_ref(&mut self, offset: CodeOffset, id: RefID) -> PartialVMResult<AbstractValue> {
              if !self.is_readable(id, None) {
                  return Err(self.error(StatusCode::READREF_EXISTS_MUTABLE_BORROW_ERROR, offset));
              }
      
              self.release(id);
              Ok(AbstractValue::NonReference)
          }
      *)
      Definition read_ref (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; id ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let id := M.alloc (| id |) 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
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "is_readable",
                                        []
                                      |),
                                      [
                                        M.read (| self |);
                                        M.read (| id |);
                                        Value.StructTuple "core::option::Option::None" []
                                      ]
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::READREF_EXISTS_MUTABLE_BORROW_ERROR"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "release",
                          []
                        |),
                        [ M.read (| self |); M.read (| id |) ]
                      |)
                    |) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                          []
                      ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_read_ref : M.IsAssociatedFunction Self "read_ref" read_ref.
      
      (*
          pub fn write_ref(&mut self, offset: CodeOffset, id: RefID) -> PartialVMResult<()> {
              if !self.is_writable(id) {
                  return Err(self.error(StatusCode::WRITEREF_EXISTS_BORROW_ERROR, offset));
              }
      
              self.release(id);
              Ok(())
          }
      *)
      Definition write_ref (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; id ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let id := M.alloc (| id |) 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
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "is_writable",
                                        []
                                      |),
                                      [ M.read (| self |); M.read (| id |) ]
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::WRITEREF_EXISTS_BORROW_ERROR"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "release",
                          []
                        |),
                        [ M.read (| self |); M.read (| id |) ]
                      |)
                    |) in
                  M.alloc (| Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ] |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_write_ref : M.IsAssociatedFunction Self "write_ref" write_ref.
      
      (*
          pub fn borrow_loc(
              &mut self,
              offset: CodeOffset,
              mut_: bool,
              local: LocalIndex,
          ) -> PartialVMResult<AbstractValue> {
              // nothing to check in case borrow is mutable since the frame cannot have an full borrow/
              // epsilon outgoing edge
              if !mut_ && self.is_local_mutably_borrowed(local) {
                  return Err(self.error(StatusCode::BORROWLOC_EXISTS_BORROW_ERROR, offset));
              }
      
              let new_id = self.new_ref(mut_);
              self.add_local_borrow(local, new_id);
              Ok(AbstractValue::Reference(new_id))
          }
      *)
      Definition borrow_loc (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; mut_; local ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let mut_ := M.alloc (| mut_ |) in
            let local := M.alloc (| local |) 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 (|
                                  LogicalOp.and (|
                                    UnOp.not (| M.read (| mut_ |) |),
                                    ltac:(M.monadic
                                      (M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                          "is_local_mutably_borrowed",
                                          []
                                        |),
                                        [ M.read (| self |); M.read (| local |) ]
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::BORROWLOC_EXISTS_BORROW_ERROR"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ new_id :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "new_ref",
                          []
                        |),
                        [ M.read (| self |); M.read (| mut_ |) ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "add_local_borrow",
                          []
                        |),
                        [ M.read (| self |); M.read (| local |); M.read (| new_id |) ]
                      |)
                    |) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                          [ M.read (| new_id |) ]
                      ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_borrow_loc : M.IsAssociatedFunction Self "borrow_loc" borrow_loc.
      
      (*
          pub fn borrow_field(
              &mut self,
              offset: CodeOffset,
              mut_: bool,
              id: RefID,
              field: FieldHandleIndex,
          ) -> PartialVMResult<AbstractValue> {
              // Any field borrows will be factored out, so don't check in the mutable case
              let is_mut_borrow_with_full_borrows = || mut_ && self.has_full_borrows(id);
              // For new immutable borrow, the reference must be readable at that field
              // This means that there could exist a mutable borrow on some other field
              let is_imm_borrow_with_mut_borrows = || !mut_ && !self.is_readable(id, Some(field));
      
              if is_mut_borrow_with_full_borrows() || is_imm_borrow_with_mut_borrows() {
                  // TODO improve error for mutable case
                  return Err(self.error(StatusCode::BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR, offset));
              }
      
              let field_borrow_id = self.new_ref(mut_);
              self.add_field_borrow(id, field, field_borrow_id);
              self.release(id);
              Ok(AbstractValue::Reference(field_borrow_id))
          }
      *)
      Definition borrow_field (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; mut_; id; field ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let mut_ := M.alloc (| mut_ |) in
            let id := M.alloc (| id |) in
            let field := M.alloc (| field |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ is_mut_borrow_with_full_borrows :=
                    M.alloc (|
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (LogicalOp.and (|
                                          M.read (| mut_ |),
                                          ltac:(M.monadic
                                            (M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path
                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                "has_full_borrows",
                                                []
                                              |),
                                              [ M.read (| self |); M.read (| id |) ]
                                            |)))
                                        |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |) in
                  let~ is_imm_borrow_with_mut_borrows :=
                    M.alloc (|
                      M.closure
                        (fun γ =>
                          ltac:(M.monadic
                            match γ with
                            | [ α0 ] =>
                              ltac:(M.monadic
                                (M.match_operator (|
                                  M.alloc (| α0 |),
                                  [
                                    fun γ =>
                                      ltac:(M.monadic
                                        (LogicalOp.and (|
                                          UnOp.not (| M.read (| mut_ |) |),
                                          ltac:(M.monadic
                                            (UnOp.not (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path
                                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                  "is_readable",
                                                  []
                                                |),
                                                [
                                                  M.read (| self |);
                                                  M.read (| id |);
                                                  Value.StructTuple
                                                    "core::option::Option::Some"
                                                    [ M.read (| field |) ]
                                                ]
                                              |)
                                            |)))
                                        |)))
                                  ]
                                |)))
                            | _ => M.impossible "wrong number of arguments"
                            end))
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.or (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::function::Fn",
                                        Ty.function [ Ty.tuple [] ] (Ty.path "bool"),
                                        [ Ty.tuple [] ],
                                        "call",
                                        []
                                      |),
                                      [ is_mut_borrow_with_full_borrows; Value.Tuple [] ]
                                    |),
                                    ltac:(M.monadic
                                      (M.call_closure (|
                                        M.get_trait_method (|
                                          "core::ops::function::Fn",
                                          Ty.function [ Ty.tuple [] ] (Ty.path "bool"),
                                          [ Ty.tuple [] ],
                                          "call",
                                          []
                                        |),
                                        [ is_imm_borrow_with_mut_borrows; Value.Tuple [] ]
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::BORROWFIELD_EXISTS_MUTABLE_BORROW_ERROR"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ field_borrow_id :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "new_ref",
                          []
                        |),
                        [ M.read (| self |); M.read (| mut_ |) ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "add_field_borrow",
                          []
                        |),
                        [
                          M.read (| self |);
                          M.read (| id |);
                          M.read (| field |);
                          M.read (| field_borrow_id |)
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "release",
                          []
                        |),
                        [ M.read (| self |); M.read (| id |) ]
                      |)
                    |) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                          [ M.read (| field_borrow_id |) ]
                      ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_borrow_field :
        M.IsAssociatedFunction Self "borrow_field" borrow_field.
      
      (*
          pub fn borrow_global(
              &mut self,
              offset: CodeOffset,
              mut_: bool,
              resource: StructDefinitionIndex,
          ) -> PartialVMResult<AbstractValue> {
              if (mut_ && self.is_global_borrowed(resource)) || self.is_global_mutably_borrowed(resource)
              {
                  return Err(self.error(StatusCode::GLOBAL_REFERENCE_ERROR, offset));
              }
      
              let new_id = self.new_ref(mut_);
              self.add_resource_borrow(resource, new_id);
              Ok(AbstractValue::Reference(new_id))
          }
      *)
      Definition borrow_global (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; mut_; resource ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let mut_ := M.alloc (| mut_ |) in
            let resource := M.alloc (| resource |) 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 (|
                                  LogicalOp.or (|
                                    LogicalOp.and (|
                                      M.read (| mut_ |),
                                      ltac:(M.monadic
                                        (M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "is_global_borrowed",
                                            []
                                          |),
                                          [ M.read (| self |); M.read (| resource |) ]
                                        |)))
                                    |),
                                    ltac:(M.monadic
                                      (M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                          "is_global_mutably_borrowed",
                                          []
                                        |),
                                        [ M.read (| self |); M.read (| resource |) ]
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::GLOBAL_REFERENCE_ERROR"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ new_id :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "new_ref",
                          []
                        |),
                        [ M.read (| self |); M.read (| mut_ |) ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "add_resource_borrow",
                          []
                        |),
                        [ M.read (| self |); M.read (| resource |); M.read (| new_id |) ]
                      |)
                    |) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                          [ M.read (| new_id |) ]
                      ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_borrow_global :
        M.IsAssociatedFunction Self "borrow_global" borrow_global.
      
      (*
          pub fn move_from(
              &mut self,
              offset: CodeOffset,
              resource: StructDefinitionIndex,
          ) -> PartialVMResult<AbstractValue> {
              if self.is_global_borrowed(resource) {
                  Err(self.error(StatusCode::GLOBAL_REFERENCE_ERROR, offset))
              } else {
                  Ok(AbstractValue::NonReference)
              }
          }
      *)
      Definition move_from (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; resource ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let resource := M.alloc (| resource |) in
            M.read (|
              M.match_operator (|
                M.alloc (| Value.Tuple [] |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ :=
                        M.use
                          (M.alloc (|
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                "is_global_borrowed",
                                []
                              |),
                              [ M.read (| self |); M.read (| resource |) ]
                            |)
                          |)) in
                      let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                      M.alloc (|
                        Value.StructTuple
                          "core::result::Result::Err"
                          [
                            M.call_closure (|
                              M.get_associated_function (|
                                Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                "error",
                                []
                              |),
                              [
                                M.read (| self |);
                                Value.StructTuple
                                  "move_core_types::vm_status::StatusCode::GLOBAL_REFERENCE_ERROR"
                                  [];
                                M.read (| offset |)
                              ]
                            |)
                          ]
                      |)));
                  fun γ =>
                    ltac:(M.monadic
                      (M.alloc (|
                        Value.StructTuple
                          "core::result::Result::Ok"
                          [
                            Value.StructTuple
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                              []
                          ]
                      |)))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_move_from : M.IsAssociatedFunction Self "move_from" move_from.
      
      (*
          pub fn vector_op(
              &mut self,
              offset: CodeOffset,
              vector: AbstractValue,
              mut_: bool,
          ) -> PartialVMResult<()> {
              let id = safe_unwrap!(vector.ref_id());
              if mut_ && !self.is_writable(id) {
                  return Err(self.error(StatusCode::VEC_UPDATE_EXISTS_MUTABLE_BORROW_ERROR, offset));
              }
              self.release(id);
              Ok(())
          }
      *)
      Definition vector_op (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; vector; mut_ ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let vector := M.alloc (| vector |) in
            let mut_ := M.alloc (| mut_ |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ id :=
                    M.copy (|
                      M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue",
                              "ref_id",
                              []
                            |),
                            [ vector ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let x := M.copy (| γ0_0 |) in
                              x));
                          fun γ =>
                            ltac:(M.monadic
                              (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                              let~ err :=
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "move_binary_format::errors::PartialVMError",
                                      "with_message",
                                      []
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "move_binary_format::errors::PartialVMError",
                                          "new",
                                          []
                                        |),
                                        [
                                          Value.StructTuple
                                            "move_core_types::vm_status::StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR"
                                            []
                                        ]
                                      |);
                                      M.call_closure (|
                                        M.get_function (|
                                          "core::hint::must_use",
                                          [ Ty.path "alloc::string::String" ]
                                        |),
                                        [
                                          M.read (|
                                            let~ res :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_function (| "alloc::fmt::format", [] |),
                                                  [
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "core::fmt::Arguments",
                                                        "new_v1",
                                                        []
                                                      |),
                                                      [
                                                        M.alloc (|
                                                          Value.Array
                                                            [
                                                              M.read (|
                                                                Value.String
                                                                  "crates/move-bytecode-verifier/src/reference_safety/abstract_state.rs:486 (none)"
                                                              |)
                                                            ]
                                                        |);
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path "core::fmt::rt::Argument",
                                                              "none",
                                                              []
                                                            |),
                                                            []
                                                          |)
                                                        |)
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              |) in
                                            res
                                          |)
                                        ]
                                      |)
                                    ]
                                  |)
                                |) in
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ := M.use (M.alloc (| Value.Bool true |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.call_closure (|
                                            M.get_function (| "core::panicking::panic_fmt", [] |),
                                            [
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "core::fmt::Arguments",
                                                  "new_v1",
                                                  []
                                                |),
                                                [
                                                  M.alloc (|
                                                    Value.Array [ M.read (| Value.String "" |) ]
                                                  |);
                                                  M.alloc (|
                                                    Value.Array
                                                      [
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path "core::fmt::rt::Argument",
                                                            "new_debug",
                                                            [
                                                              Ty.path
                                                                "move_binary_format::errors::PartialVMError"
                                                            ]
                                                          |),
                                                          [ err ]
                                                        |)
                                                      ]
                                                  |)
                                                ]
                                              |)
                                            ]
                                          |)
                                        |)
                                      |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [ M.read (| err |) ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                ]
                              |)))
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.and (|
                                    M.read (| mut_ |),
                                    ltac:(M.monadic
                                      (UnOp.not (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "is_writable",
                                            []
                                          |),
                                          [ M.read (| self |); M.read (| id |) ]
                                        |)
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::VEC_UPDATE_EXISTS_MUTABLE_BORROW_ERROR"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "release",
                          []
                        |),
                        [ M.read (| self |); M.read (| id |) ]
                      |)
                    |) in
                  M.alloc (| Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ] |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_vector_op : M.IsAssociatedFunction Self "vector_op" vector_op.
      
      (*
          pub fn vector_element_borrow(
              &mut self,
              offset: CodeOffset,
              vector: AbstractValue,
              mut_: bool,
          ) -> PartialVMResult<AbstractValue> {
              let vec_id = safe_unwrap!(vector.ref_id());
              if mut_ && !self.is_writable(vec_id) {
                  return Err(self.error(
                      StatusCode::VEC_BORROW_ELEMENT_EXISTS_MUTABLE_BORROW_ERROR,
                      offset,
                  ));
              }
      
              let elem_id = self.new_ref(mut_);
              self.add_borrow(vec_id, elem_id);
      
              self.release(vec_id);
              Ok(AbstractValue::Reference(elem_id))
          }
      *)
      Definition vector_element_borrow (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; vector; mut_ ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let vector := M.alloc (| vector |) in
            let mut_ := M.alloc (| mut_ |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ vec_id :=
                    M.copy (|
                      M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.path
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue",
                              "ref_id",
                              []
                            |),
                            [ vector ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::option::Option::Some",
                                  0
                                |) in
                              let x := M.copy (| γ0_0 |) in
                              x));
                          fun γ =>
                            ltac:(M.monadic
                              (let _ := M.is_struct_tuple (| γ, "core::option::Option::None" |) in
                              let~ err :=
                                M.alloc (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path "move_binary_format::errors::PartialVMError",
                                      "with_message",
                                      []
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.path "move_binary_format::errors::PartialVMError",
                                          "new",
                                          []
                                        |),
                                        [
                                          Value.StructTuple
                                            "move_core_types::vm_status::StatusCode::UNKNOWN_INVARIANT_VIOLATION_ERROR"
                                            []
                                        ]
                                      |);
                                      M.call_closure (|
                                        M.get_function (|
                                          "core::hint::must_use",
                                          [ Ty.path "alloc::string::String" ]
                                        |),
                                        [
                                          M.read (|
                                            let~ res :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_function (| "alloc::fmt::format", [] |),
                                                  [
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path "core::fmt::Arguments",
                                                        "new_v1",
                                                        []
                                                      |),
                                                      [
                                                        M.alloc (|
                                                          Value.Array
                                                            [
                                                              M.read (|
                                                                Value.String
                                                                  "crates/move-bytecode-verifier/src/reference_safety/abstract_state.rs:500 (none)"
                                                              |)
                                                            ]
                                                        |);
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path "core::fmt::rt::Argument",
                                                              "none",
                                                              []
                                                            |),
                                                            []
                                                          |)
                                                        |)
                                                      ]
                                                    |)
                                                  ]
                                                |)
                                              |) in
                                            res
                                          |)
                                        ]
                                      |)
                                    ]
                                  |)
                                |) in
                              M.match_operator (|
                                M.alloc (| Value.Tuple [] |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ := M.use (M.alloc (| Value.Bool true |)) in
                                      let _ :=
                                        M.is_constant_or_break_match (|
                                          M.read (| γ |),
                                          Value.Bool true
                                        |) in
                                      M.alloc (|
                                        M.never_to_any (|
                                          M.call_closure (|
                                            M.get_function (| "core::panicking::panic_fmt", [] |),
                                            [
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path "core::fmt::Arguments",
                                                  "new_v1",
                                                  []
                                                |),
                                                [
                                                  M.alloc (|
                                                    Value.Array [ M.read (| Value.String "" |) ]
                                                  |);
                                                  M.alloc (|
                                                    Value.Array
                                                      [
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.path "core::fmt::rt::Argument",
                                                            "new_debug",
                                                            [
                                                              Ty.path
                                                                "move_binary_format::errors::PartialVMError"
                                                            ]
                                                          |),
                                                          [ err ]
                                                        |)
                                                      ]
                                                  |)
                                                ]
                                              |)
                                            ]
                                          |)
                                        |)
                                      |)));
                                  fun γ =>
                                    ltac:(M.monadic
                                      (M.alloc (|
                                        M.never_to_any (|
                                          M.read (|
                                            M.return_ (|
                                              Value.StructTuple
                                                "core::result::Result::Err"
                                                [ M.read (| err |) ]
                                            |)
                                          |)
                                        |)
                                      |)))
                                ]
                              |)))
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  LogicalOp.and (|
                                    M.read (| mut_ |),
                                    ltac:(M.monadic
                                      (UnOp.not (|
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "is_writable",
                                            []
                                          |),
                                          [ M.read (| self |); M.read (| vec_id |) ]
                                        |)
                                      |)))
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::VEC_BORROW_ELEMENT_EXISTS_MUTABLE_BORROW_ERROR"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ elem_id :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "new_ref",
                          []
                        |),
                        [ M.read (| self |); M.read (| mut_ |) ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "add_borrow",
                          []
                        |),
                        [ M.read (| self |); M.read (| vec_id |); M.read (| elem_id |) ]
                      |)
                    |) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "release",
                          []
                        |),
                        [ M.read (| self |); M.read (| vec_id |) ]
                      |)
                    |) in
                  M.alloc (|
                    Value.StructTuple
                      "core::result::Result::Ok"
                      [
                        Value.StructTuple
                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                          [ M.read (| elem_id |) ]
                      ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_vector_element_borrow :
        M.IsAssociatedFunction Self "vector_element_borrow" vector_element_borrow.
      
      (*
          pub fn call(
              &mut self,
              offset: CodeOffset,
              arguments: Vec<AbstractValue>,
              acquired_resources: &BTreeSet<StructDefinitionIndex>,
              return_: &Signature,
              meter: &mut (impl Meter + ?Sized),
          ) -> PartialVMResult<Vec<AbstractValue>> {
              meter.add_items(
                  Scope::Function,
                  CALL_PER_ACQUIRES_COST,
                  acquired_resources.len(),
              )?;
              // Check acquires
              for acquired_resource in acquired_resources {
                  if self.is_global_borrowed( *acquired_resource) {
                      return Err(self.error(StatusCode::GLOBAL_REFERENCE_ERROR, offset));
                  }
              }
      
              // Check mutable references can be transferred
              let mut all_references_to_borrow_from = BTreeSet::new();
              let mut mutable_references_to_borrow_from = BTreeSet::new();
              for id in arguments.iter().filter_map(|v| v.ref_id()) {
                  if self.borrow_graph.is_mutable(id) {
                      if !self.is_writable(id) {
                          return Err(
                              self.error(StatusCode::CALL_BORROWED_MUTABLE_REFERENCE_ERROR, offset)
                          );
                      }
                      mutable_references_to_borrow_from.insert(id);
                  }
                  all_references_to_borrow_from.insert(id);
              }
      
              // Track borrow relationships of return values on inputs
              let mut returned_refs = 0;
              let return_values = return_
                  .0
                  .iter()
                  .map(|return_type| match return_type {
                      SignatureToken::MutableReference(_) => {
                          let id = self.new_ref(true);
                          for parent in &mutable_references_to_borrow_from {
                              self.add_borrow( *parent, id);
                          }
                          returned_refs += 1;
                          AbstractValue::Reference(id)
                      }
                      SignatureToken::Reference(_) => {
                          let id = self.new_ref(false);
                          for parent in &all_references_to_borrow_from {
                              self.add_borrow( *parent, id);
                          }
                          returned_refs += 1;
                          AbstractValue::Reference(id)
                      }
                      _ => AbstractValue::NonReference,
                  })
                  .collect();
      
              // Meter usage of reference edges
              meter.add_items_with_growth(
                  Scope::Function,
                  REF_PARAM_EDGE_COST,
                  all_references_to_borrow_from
                      .len()
                      .saturating_mul(returned_refs),
                  REF_PARAM_EDGE_COST_GROWTH,
              )?;
      
              // Release input references
              for id in all_references_to_borrow_from {
                  self.release(id)
              }
              Ok(return_values)
          }
      *)
      Definition call (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [],
            [ impl_Meter__plus___Sized ],
            [ self; offset; arguments; acquired_resources; return_; meter ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let arguments := M.alloc (| arguments |) in
            let acquired_resources := M.alloc (| acquired_resources |) in
            let return_ := M.alloc (| return_ |) in
            let meter := M.alloc (| meter |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::try_trait::Try",
                            Ty.apply
                              (Ty.path "core::result::Result")
                              []
                              [ Ty.tuple []; Ty.path "move_binary_format::errors::PartialVMError" ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "move_bytecode_verifier_meter::Meter",
                                impl_Meter__plus___Sized,
                                [],
                                "add_items",
                                []
                              |),
                              [
                                M.read (| meter |);
                                Value.StructTuple
                                  "move_bytecode_verifier_meter::Scope::Function"
                                  [];
                                M.read (|
                                  M.get_constant (|
                                    "move_bytecode_verifier::reference_safety::abstract_state::CALL_PER_ACQUIRES_COST"
                                  |)
                                |);
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply
                                      (Ty.path "alloc::collections::btree::set::BTreeSet")
                                      []
                                      [
                                        Ty.path
                                          "move_binary_format::file_format::StructDefinitionIndex";
                                        Ty.path "alloc::alloc::Global"
                                      ],
                                    "len",
                                    []
                                  |),
                                  [ M.read (| acquired_resources |) ]
                                |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Break",
                                0
                              |) in
                            let residual := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::FromResidual",
                                        Ty.apply
                                          (Ty.path "core::result::Result")
                                          []
                                          [
                                            Ty.apply
                                              (Ty.path "alloc::vec::Vec")
                                              []
                                              [
                                                Ty.path
                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                                Ty.path "alloc::alloc::Global"
                                              ];
                                            Ty.path "move_binary_format::errors::PartialVMError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            []
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "move_binary_format::errors::PartialVMError"
                                            ]
                                        ],
                                        "from_residual",
                                        []
                                      |),
                                      [ M.read (| residual |) ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Continue",
                                0
                              |) in
                            let val := M.copy (| γ0_0 |) in
                            val))
                      ]
                    |) in
                  let~ _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "&")
                                []
                                [
                                  Ty.apply
                                    (Ty.path "alloc::collections::btree::set::BTreeSet")
                                    []
                                    [
                                      Ty.path
                                        "move_binary_format::file_format::StructDefinitionIndex";
                                      Ty.path "alloc::alloc::Global"
                                    ]
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [ M.read (| acquired_resources |) ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "alloc::collections::btree::set::Iter")
                                              []
                                              [
                                                Ty.path
                                                  "move_binary_format::file_format::StructDefinitionIndex"
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::option::Option::None"
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let acquired_resource := M.copy (| γ0_0 |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path
                                                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                              "is_global_borrowed",
                                                              []
                                                            |),
                                                            [
                                                              M.read (| self |);
                                                              M.read (|
                                                                M.read (| acquired_resource |)
                                                              |)
                                                            ]
                                                          |)
                                                        |)) in
                                                    let _ :=
                                                      M.is_constant_or_break_match (|
                                                        M.read (| γ |),
                                                        Value.Bool true
                                                      |) in
                                                    M.alloc (|
                                                      M.never_to_any (|
                                                        M.read (|
                                                          M.return_ (|
                                                            Value.StructTuple
                                                              "core::result::Result::Err"
                                                              [
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path
                                                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                    "error",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.read (| self |);
                                                                    Value.StructTuple
                                                                      "move_core_types::vm_status::StatusCode::GLOBAL_REFERENCE_ERROR"
                                                                      [];
                                                                    M.read (| offset |)
                                                                  ]
                                                                |)
                                                              ]
                                                          |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  let~ all_references_to_borrow_from :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::collections::btree::set::BTreeSet")
                            []
                            [
                              Ty.path "move_borrow_graph::references::RefID";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "new",
                          []
                        |),
                        []
                      |)
                    |) in
                  let~ mutable_references_to_borrow_from :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::collections::btree::set::BTreeSet")
                            []
                            [
                              Ty.path "move_borrow_graph::references::RefID";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "new",
                          []
                        |),
                        []
                      |)
                    |) in
                  let~ _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "core::iter::adapters::filter_map::FilterMap")
                                []
                                [
                                  Ty.apply
                                    (Ty.path "core::slice::iter::Iter")
                                    []
                                    [
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                    ];
                                  Ty.function
                                    [
                                      Ty.tuple
                                        [
                                          Ty.apply
                                            (Ty.path "&")
                                            []
                                            [
                                              Ty.path
                                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                            ]
                                        ]
                                    ]
                                    (Ty.apply
                                      (Ty.path "core::option::Option")
                                      []
                                      [ Ty.path "move_borrow_graph::references::RefID" ])
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::iterator::Iterator",
                                  Ty.apply
                                    (Ty.path "core::slice::iter::Iter")
                                    []
                                    [
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                    ],
                                  [],
                                  "filter_map",
                                  [
                                    Ty.path "move_borrow_graph::references::RefID";
                                    Ty.function
                                      [
                                        Ty.tuple
                                          [
                                            Ty.apply
                                              (Ty.path "&")
                                              []
                                              [
                                                Ty.path
                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                              ]
                                          ]
                                      ]
                                      (Ty.apply
                                        (Ty.path "core::option::Option")
                                        []
                                        [ Ty.path "move_borrow_graph::references::RefID" ])
                                  ]
                                |),
                                [
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "slice")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                        ],
                                      "iter",
                                      []
                                    |),
                                    [
                                      M.call_closure (|
                                        M.get_trait_method (|
                                          "core::ops::deref::Deref",
                                          Ty.apply
                                            (Ty.path "alloc::vec::Vec")
                                            []
                                            [
                                              Ty.path
                                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                              Ty.path "alloc::alloc::Global"
                                            ],
                                          [],
                                          "deref",
                                          []
                                        |),
                                        [ arguments ]
                                      |)
                                    ]
                                  |);
                                  M.closure
                                    (fun γ =>
                                      ltac:(M.monadic
                                        match γ with
                                        | [ α0 ] =>
                                          ltac:(M.monadic
                                            (M.match_operator (|
                                              M.alloc (| α0 |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let v := M.copy (| γ |) in
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue",
                                                        "ref_id",
                                                        []
                                                      |),
                                                      [ M.read (| v |) ]
                                                    |)))
                                              ]
                                            |)))
                                        | _ => M.impossible "wrong number of arguments"
                                        end))
                                ]
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path
                                                "core::iter::adapters::filter_map::FilterMap")
                                              []
                                              [
                                                Ty.apply
                                                  (Ty.path "core::slice::iter::Iter")
                                                  []
                                                  [
                                                    Ty.path
                                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                                  ];
                                                Ty.function
                                                  [
                                                    Ty.tuple
                                                      [
                                                        Ty.apply
                                                          (Ty.path "&")
                                                          []
                                                          [
                                                            Ty.path
                                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                                          ]
                                                      ]
                                                  ]
                                                  (Ty.apply
                                                    (Ty.path "core::option::Option")
                                                    []
                                                    [ Ty.path "move_borrow_graph::references::RefID"
                                                    ])
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::option::Option::None"
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let id := M.copy (| γ0_0 |) in
                                            let~ _ :=
                                              M.match_operator (|
                                                M.alloc (| Value.Tuple [] |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ :=
                                                        M.use
                                                          (M.alloc (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.apply
                                                                  (Ty.path
                                                                    "move_borrow_graph::graph::BorrowGraph")
                                                                  []
                                                                  [
                                                                    Ty.tuple [];
                                                                    Ty.path
                                                                      "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                                                  ],
                                                                "is_mutable",
                                                                []
                                                              |),
                                                              [
                                                                M.SubPointer.get_struct_record_field (|
                                                                  M.read (| self |),
                                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                  "borrow_graph"
                                                                |);
                                                                M.read (| id |)
                                                              ]
                                                            |)
                                                          |)) in
                                                      let _ :=
                                                        M.is_constant_or_break_match (|
                                                          M.read (| γ |),
                                                          Value.Bool true
                                                        |) in
                                                      let~ _ :=
                                                        M.match_operator (|
                                                          M.alloc (| Value.Tuple [] |),
                                                          [
                                                            fun γ =>
                                                              ltac:(M.monadic
                                                                (let γ :=
                                                                  M.use
                                                                    (M.alloc (|
                                                                      UnOp.not (|
                                                                        M.call_closure (|
                                                                          M.get_associated_function (|
                                                                            Ty.path
                                                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                            "is_writable",
                                                                            []
                                                                          |),
                                                                          [
                                                                            M.read (| self |);
                                                                            M.read (| id |)
                                                                          ]
                                                                        |)
                                                                      |)
                                                                    |)) in
                                                                let _ :=
                                                                  M.is_constant_or_break_match (|
                                                                    M.read (| γ |),
                                                                    Value.Bool true
                                                                  |) in
                                                                M.alloc (|
                                                                  M.never_to_any (|
                                                                    M.read (|
                                                                      M.return_ (|
                                                                        Value.StructTuple
                                                                          "core::result::Result::Err"
                                                                          [
                                                                            M.call_closure (|
                                                                              M.get_associated_function (|
                                                                                Ty.path
                                                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                                "error",
                                                                                []
                                                                              |),
                                                                              [
                                                                                M.read (| self |);
                                                                                Value.StructTuple
                                                                                  "move_core_types::vm_status::StatusCode::CALL_BORROWED_MUTABLE_REFERENCE_ERROR"
                                                                                  [];
                                                                                M.read (| offset |)
                                                                              ]
                                                                            |)
                                                                          ]
                                                                      |)
                                                                    |)
                                                                  |)
                                                                |)));
                                                            fun γ =>
                                                              ltac:(M.monadic
                                                                (M.alloc (| Value.Tuple [] |)))
                                                          ]
                                                        |) in
                                                      let~ _ :=
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path
                                                                  "alloc::collections::btree::set::BTreeSet")
                                                                []
                                                                [
                                                                  Ty.path
                                                                    "move_borrow_graph::references::RefID";
                                                                  Ty.path "alloc::alloc::Global"
                                                                ],
                                                              "insert",
                                                              []
                                                            |),
                                                            [
                                                              mutable_references_to_borrow_from;
                                                              M.read (| id |)
                                                            ]
                                                          |)
                                                        |) in
                                                      M.alloc (| Value.Tuple [] |)));
                                                  fun γ =>
                                                    ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                                ]
                                              |) in
                                            let~ _ :=
                                              M.alloc (|
                                                M.call_closure (|
                                                  M.get_associated_function (|
                                                    Ty.apply
                                                      (Ty.path
                                                        "alloc::collections::btree::set::BTreeSet")
                                                      []
                                                      [
                                                        Ty.path
                                                          "move_borrow_graph::references::RefID";
                                                        Ty.path "alloc::alloc::Global"
                                                      ],
                                                    "insert",
                                                    []
                                                  |),
                                                  [ all_references_to_borrow_from; M.read (| id |) ]
                                                |)
                                              |) in
                                            M.alloc (| Value.Tuple [] |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  let~ returned_refs := M.alloc (| Value.Integer IntegerKind.Usize 0 |) in
                  let~ return_values :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          Ty.apply
                            (Ty.path "core::iter::adapters::map::Map")
                            []
                            [
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [ Ty.path "move_binary_format::file_format::SignatureToken" ];
                              Ty.function
                                [
                                  Ty.tuple
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        []
                                        [ Ty.path "move_binary_format::file_format::SignatureToken"
                                        ]
                                    ]
                                ]
                                (Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue")
                            ],
                          [],
                          "collect",
                          [
                            Ty.apply
                              (Ty.path "alloc::vec::Vec")
                              []
                              [
                                Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                Ty.path "alloc::alloc::Global"
                              ]
                          ]
                        |),
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [ Ty.path "move_binary_format::file_format::SignatureToken" ],
                              [],
                              "map",
                              [
                                Ty.path
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                Ty.function
                                  [
                                    Ty.tuple
                                      [
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [
                                            Ty.path
                                              "move_binary_format::file_format::SignatureToken"
                                          ]
                                      ]
                                  ]
                                  (Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue")
                              ]
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    []
                                    [ Ty.path "move_binary_format::file_format::SignatureToken" ],
                                  "iter",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::deref::Deref",
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path "move_binary_format::file_format::SignatureToken";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      [],
                                      "deref",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_tuple_field (|
                                        M.read (| return_ |),
                                        "move_binary_format::file_format::Signature",
                                        0
                                      |)
                                    ]
                                  |)
                                ]
                              |);
                              M.closure
                                (fun γ =>
                                  ltac:(M.monadic
                                    match γ with
                                    | [ α0 ] =>
                                      ltac:(M.monadic
                                        (M.match_operator (|
                                          M.alloc (| α0 |),
                                          [
                                            fun γ =>
                                              ltac:(M.monadic
                                                (let return_type := M.copy (| γ |) in
                                                M.read (|
                                                  M.match_operator (|
                                                    return_type,
                                                    [
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (let γ := M.read (| γ |) in
                                                          let γ1_0 :=
                                                            M.SubPointer.get_struct_tuple_field (|
                                                              γ,
                                                              "move_binary_format::file_format::SignatureToken::MutableReference",
                                                              0
                                                            |) in
                                                          let~ id :=
                                                            M.alloc (|
                                                              M.call_closure (|
                                                                M.get_associated_function (|
                                                                  Ty.path
                                                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                  "new_ref",
                                                                  []
                                                                |),
                                                                [ M.read (| self |); Value.Bool true
                                                                ]
                                                              |)
                                                            |) in
                                                          let~ _ :=
                                                            M.use
                                                              (M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_trait_method (|
                                                                      "core::iter::traits::collect::IntoIterator",
                                                                      Ty.apply
                                                                        (Ty.path "&")
                                                                        []
                                                                        [
                                                                          Ty.apply
                                                                            (Ty.path
                                                                              "alloc::collections::btree::set::BTreeSet")
                                                                            []
                                                                            [
                                                                              Ty.path
                                                                                "move_borrow_graph::references::RefID";
                                                                              Ty.path
                                                                                "alloc::alloc::Global"
                                                                            ]
                                                                        ],
                                                                      [],
                                                                      "into_iter",
                                                                      []
                                                                    |),
                                                                    [
                                                                      mutable_references_to_borrow_from
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let iter := M.copy (| γ |) in
                                                                      M.loop (|
                                                                        ltac:(M.monadic
                                                                          (let~ _ :=
                                                                            M.match_operator (|
                                                                              M.alloc (|
                                                                                M.call_closure (|
                                                                                  M.get_trait_method (|
                                                                                    "core::iter::traits::iterator::Iterator",
                                                                                    Ty.apply
                                                                                      (Ty.path
                                                                                        "alloc::collections::btree::set::Iter")
                                                                                      []
                                                                                      [
                                                                                        Ty.path
                                                                                          "move_borrow_graph::references::RefID"
                                                                                      ],
                                                                                    [],
                                                                                    "next",
                                                                                    []
                                                                                  |),
                                                                                  [ iter ]
                                                                                |)
                                                                              |),
                                                                              [
                                                                                fun γ =>
                                                                                  ltac:(M.monadic
                                                                                    (let _ :=
                                                                                      M.is_struct_tuple (|
                                                                                        γ,
                                                                                        "core::option::Option::None"
                                                                                      |) in
                                                                                    M.alloc (|
                                                                                      M.never_to_any (|
                                                                                        M.read (|
                                                                                          M.break (||)
                                                                                        |)
                                                                                      |)
                                                                                    |)));
                                                                                fun γ =>
                                                                                  ltac:(M.monadic
                                                                                    (let γ0_0 :=
                                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                                        γ,
                                                                                        "core::option::Option::Some",
                                                                                        0
                                                                                      |) in
                                                                                    let parent :=
                                                                                      M.copy (|
                                                                                        γ0_0
                                                                                      |) in
                                                                                    let~ _ :=
                                                                                      M.alloc (|
                                                                                        M.call_closure (|
                                                                                          M.get_associated_function (|
                                                                                            Ty.path
                                                                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                                            "add_borrow",
                                                                                            []
                                                                                          |),
                                                                                          [
                                                                                            M.read (|
                                                                                              self
                                                                                            |);
                                                                                            M.read (|
                                                                                              M.read (|
                                                                                                parent
                                                                                              |)
                                                                                            |);
                                                                                            M.read (|
                                                                                              id
                                                                                            |)
                                                                                          ]
                                                                                        |)
                                                                                      |) in
                                                                                    M.alloc (|
                                                                                      Value.Tuple []
                                                                                    |)))
                                                                              ]
                                                                            |) in
                                                                          M.alloc (|
                                                                            Value.Tuple []
                                                                          |)))
                                                                      |)))
                                                                ]
                                                              |)) in
                                                          let~ _ :=
                                                            let β := returned_refs in
                                                            M.write (|
                                                              β,
                                                              BinOp.Wrap.add (|
                                                                M.read (| β |),
                                                                Value.Integer IntegerKind.Usize 1
                                                              |)
                                                            |) in
                                                          M.alloc (|
                                                            Value.StructTuple
                                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                                                              [ M.read (| id |) ]
                                                          |)));
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (let γ := M.read (| γ |) in
                                                          let γ1_0 :=
                                                            M.SubPointer.get_struct_tuple_field (|
                                                              γ,
                                                              "move_binary_format::file_format::SignatureToken::Reference",
                                                              0
                                                            |) in
                                                          let~ id :=
                                                            M.alloc (|
                                                              M.call_closure (|
                                                                M.get_associated_function (|
                                                                  Ty.path
                                                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                  "new_ref",
                                                                  []
                                                                |),
                                                                [
                                                                  M.read (| self |);
                                                                  Value.Bool false
                                                                ]
                                                              |)
                                                            |) in
                                                          let~ _ :=
                                                            M.use
                                                              (M.match_operator (|
                                                                M.alloc (|
                                                                  M.call_closure (|
                                                                    M.get_trait_method (|
                                                                      "core::iter::traits::collect::IntoIterator",
                                                                      Ty.apply
                                                                        (Ty.path "&")
                                                                        []
                                                                        [
                                                                          Ty.apply
                                                                            (Ty.path
                                                                              "alloc::collections::btree::set::BTreeSet")
                                                                            []
                                                                            [
                                                                              Ty.path
                                                                                "move_borrow_graph::references::RefID";
                                                                              Ty.path
                                                                                "alloc::alloc::Global"
                                                                            ]
                                                                        ],
                                                                      [],
                                                                      "into_iter",
                                                                      []
                                                                    |),
                                                                    [ all_references_to_borrow_from
                                                                    ]
                                                                  |)
                                                                |),
                                                                [
                                                                  fun γ =>
                                                                    ltac:(M.monadic
                                                                      (let iter := M.copy (| γ |) in
                                                                      M.loop (|
                                                                        ltac:(M.monadic
                                                                          (let~ _ :=
                                                                            M.match_operator (|
                                                                              M.alloc (|
                                                                                M.call_closure (|
                                                                                  M.get_trait_method (|
                                                                                    "core::iter::traits::iterator::Iterator",
                                                                                    Ty.apply
                                                                                      (Ty.path
                                                                                        "alloc::collections::btree::set::Iter")
                                                                                      []
                                                                                      [
                                                                                        Ty.path
                                                                                          "move_borrow_graph::references::RefID"
                                                                                      ],
                                                                                    [],
                                                                                    "next",
                                                                                    []
                                                                                  |),
                                                                                  [ iter ]
                                                                                |)
                                                                              |),
                                                                              [
                                                                                fun γ =>
                                                                                  ltac:(M.monadic
                                                                                    (let _ :=
                                                                                      M.is_struct_tuple (|
                                                                                        γ,
                                                                                        "core::option::Option::None"
                                                                                      |) in
                                                                                    M.alloc (|
                                                                                      M.never_to_any (|
                                                                                        M.read (|
                                                                                          M.break (||)
                                                                                        |)
                                                                                      |)
                                                                                    |)));
                                                                                fun γ =>
                                                                                  ltac:(M.monadic
                                                                                    (let γ0_0 :=
                                                                                      M.SubPointer.get_struct_tuple_field (|
                                                                                        γ,
                                                                                        "core::option::Option::Some",
                                                                                        0
                                                                                      |) in
                                                                                    let parent :=
                                                                                      M.copy (|
                                                                                        γ0_0
                                                                                      |) in
                                                                                    let~ _ :=
                                                                                      M.alloc (|
                                                                                        M.call_closure (|
                                                                                          M.get_associated_function (|
                                                                                            Ty.path
                                                                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                                            "add_borrow",
                                                                                            []
                                                                                          |),
                                                                                          [
                                                                                            M.read (|
                                                                                              self
                                                                                            |);
                                                                                            M.read (|
                                                                                              M.read (|
                                                                                                parent
                                                                                              |)
                                                                                            |);
                                                                                            M.read (|
                                                                                              id
                                                                                            |)
                                                                                          ]
                                                                                        |)
                                                                                      |) in
                                                                                    M.alloc (|
                                                                                      Value.Tuple []
                                                                                    |)))
                                                                              ]
                                                                            |) in
                                                                          M.alloc (|
                                                                            Value.Tuple []
                                                                          |)))
                                                                      |)))
                                                                ]
                                                              |)) in
                                                          let~ _ :=
                                                            let β := returned_refs in
                                                            M.write (|
                                                              β,
                                                              BinOp.Wrap.add (|
                                                                M.read (| β |),
                                                                Value.Integer IntegerKind.Usize 1
                                                              |)
                                                            |) in
                                                          M.alloc (|
                                                            Value.StructTuple
                                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                                                              [ M.read (| id |) ]
                                                          |)));
                                                      fun γ =>
                                                        ltac:(M.monadic
                                                          (M.alloc (|
                                                            Value.StructTuple
                                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                                                              []
                                                          |)))
                                                    ]
                                                  |)
                                                |)))
                                          ]
                                        |)))
                                    | _ => M.impossible "wrong number of arguments"
                                    end))
                            ]
                          |)
                        ]
                      |)
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::try_trait::Try",
                            Ty.apply
                              (Ty.path "core::result::Result")
                              []
                              [ Ty.tuple []; Ty.path "move_binary_format::errors::PartialVMError" ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "move_bytecode_verifier_meter::Meter",
                                impl_Meter__plus___Sized,
                                [],
                                "add_items_with_growth",
                                []
                              |),
                              [
                                M.read (| meter |);
                                Value.StructTuple
                                  "move_bytecode_verifier_meter::Scope::Function"
                                  [];
                                M.read (|
                                  M.get_constant (|
                                    "move_bytecode_verifier::reference_safety::abstract_state::REF_PARAM_EDGE_COST"
                                  |)
                                |);
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path "usize",
                                    "saturating_mul",
                                    []
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply
                                          (Ty.path "alloc::collections::btree::set::BTreeSet")
                                          []
                                          [
                                            Ty.path "move_borrow_graph::references::RefID";
                                            Ty.path "alloc::alloc::Global"
                                          ],
                                        "len",
                                        []
                                      |),
                                      [ all_references_to_borrow_from ]
                                    |);
                                    M.read (| returned_refs |)
                                  ]
                                |);
                                M.read (|
                                  M.get_constant (|
                                    "move_bytecode_verifier::reference_safety::abstract_state::REF_PARAM_EDGE_COST_GROWTH"
                                  |)
                                |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Break",
                                0
                              |) in
                            let residual := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::FromResidual",
                                        Ty.apply
                                          (Ty.path "core::result::Result")
                                          []
                                          [
                                            Ty.apply
                                              (Ty.path "alloc::vec::Vec")
                                              []
                                              [
                                                Ty.path
                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                                Ty.path "alloc::alloc::Global"
                                              ];
                                            Ty.path "move_binary_format::errors::PartialVMError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            []
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "move_binary_format::errors::PartialVMError"
                                            ]
                                        ],
                                        "from_residual",
                                        []
                                      |),
                                      [ M.read (| residual |) ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Continue",
                                0
                              |) in
                            let val := M.copy (| γ0_0 |) in
                            val))
                      ]
                    |) in
                  let~ _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "alloc::collections::btree::set::BTreeSet")
                                []
                                [
                                  Ty.path "move_borrow_graph::references::RefID";
                                  Ty.path "alloc::alloc::Global"
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [ M.read (| all_references_to_borrow_from |) ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "alloc::collections::btree::set::IntoIter")
                                              []
                                              [
                                                Ty.path "move_borrow_graph::references::RefID";
                                                Ty.path "alloc::alloc::Global"
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::option::Option::None"
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let id := M.copy (| γ0_0 |) in
                                            M.alloc (|
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path
                                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                  "release",
                                                  []
                                                |),
                                                [ M.read (| self |); M.read (| id |) ]
                                              |)
                                            |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  M.alloc (|
                    Value.StructTuple "core::result::Result::Ok" [ M.read (| return_values |) ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_call : M.IsAssociatedFunction Self "call" call.
      
      (*
          pub fn ret(&mut self, offset: CodeOffset, values: Vec<AbstractValue>) -> PartialVMResult<()> {
              // release all local variables
              let mut released = BTreeSet::new();
              for stored_value in self.locals.iter() {
                  if let AbstractValue::Reference(id) = stored_value {
                      released.insert( *id);
                  }
              }
              released.into_iter().for_each(|id| self.release(id));
      
              // Check that no local or global is borrowed
              if !self.is_frame_safe_to_destroy() {
                  return Err(self.error(
                      StatusCode::UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED,
                      offset,
                  ));
              }
      
              // Check mutable references can be transferred
              for id in values.into_iter().filter_map(|v| v.ref_id()) {
                  if self.borrow_graph.is_mutable(id) && !self.is_writable(id) {
                      return Err(self.error(StatusCode::RET_BORROWED_MUTABLE_REFERENCE_ERROR, offset));
                  }
              }
              Ok(())
          }
      *)
      Definition ret (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; offset; values ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let offset := M.alloc (| offset |) in
            let values := M.alloc (| values |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ released :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply
                            (Ty.path "alloc::collections::btree::set::BTreeSet")
                            []
                            [
                              Ty.path "move_borrow_graph::references::RefID";
                              Ty.path "alloc::alloc::Global"
                            ],
                          "new",
                          []
                        |),
                        []
                      |)
                    |) in
                  let~ _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    []
                                    [
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                    ],
                                  "iter",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::deref::Deref",
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      [],
                                      "deref",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "locals"
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path "core::slice::iter::Iter")
                                              []
                                              [
                                                Ty.path
                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::option::Option::None"
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let stored_value := M.copy (| γ0_0 |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ := stored_value in
                                                    let γ := M.read (| γ |) in
                                                    let γ1_0 :=
                                                      M.SubPointer.get_struct_tuple_field (|
                                                        γ,
                                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                                        0
                                                      |) in
                                                    let id := M.alloc (| γ1_0 |) in
                                                    let~ _ :=
                                                      M.alloc (|
                                                        M.call_closure (|
                                                          M.get_associated_function (|
                                                            Ty.apply
                                                              (Ty.path
                                                                "alloc::collections::btree::set::BTreeSet")
                                                              []
                                                              [
                                                                Ty.path
                                                                  "move_borrow_graph::references::RefID";
                                                                Ty.path "alloc::alloc::Global"
                                                              ],
                                                            "insert",
                                                            []
                                                          |),
                                                          [ released; M.read (| M.read (| id |) |) ]
                                                        |)
                                                      |) in
                                                    M.alloc (| Value.Tuple [] |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  let~ _ :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          Ty.apply
                            (Ty.path "alloc::collections::btree::set::IntoIter")
                            []
                            [
                              Ty.path "move_borrow_graph::references::RefID";
                              Ty.path "alloc::alloc::Global"
                            ],
                          [],
                          "for_each",
                          [
                            Ty.function
                              [ Ty.tuple [ Ty.path "move_borrow_graph::references::RefID" ] ]
                              (Ty.tuple [])
                          ]
                        |),
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "alloc::collections::btree::set::BTreeSet")
                                []
                                [
                                  Ty.path "move_borrow_graph::references::RefID";
                                  Ty.path "alloc::alloc::Global"
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [ M.read (| released |) ]
                          |);
                          M.closure
                            (fun γ =>
                              ltac:(M.monadic
                                match γ with
                                | [ α0 ] =>
                                  ltac:(M.monadic
                                    (M.match_operator (|
                                      M.alloc (| α0 |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let id := M.copy (| γ |) in
                                            M.call_closure (|
                                              M.get_associated_function (|
                                                Ty.path
                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                "release",
                                                []
                                              |),
                                              [ M.read (| self |); M.read (| id |) ]
                                            |)))
                                      ]
                                    |)))
                                | _ => M.impossible "wrong number of arguments"
                                end))
                        ]
                      |)
                    |) 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
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "is_frame_safe_to_destroy",
                                        []
                                      |),
                                      [ M.read (| self |) ]
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [
                                        M.call_closure (|
                                          M.get_associated_function (|
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "error",
                                            []
                                          |),
                                          [
                                            M.read (| self |);
                                            Value.StructTuple
                                              "move_core_types::vm_status::StatusCode::UNSAFE_RET_LOCAL_OR_RESOURCE_STILL_BORROWED"
                                              [];
                                            M.read (| offset |)
                                          ]
                                        |)
                                      ]
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ _ :=
                    M.use
                      (M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::collect::IntoIterator",
                              Ty.apply
                                (Ty.path "core::iter::adapters::filter_map::FilterMap")
                                []
                                [
                                  Ty.apply
                                    (Ty.path "alloc::vec::into_iter::IntoIter")
                                    []
                                    [
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                      Ty.path "alloc::alloc::Global"
                                    ];
                                  Ty.function
                                    [
                                      Ty.tuple
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                        ]
                                    ]
                                    (Ty.apply
                                      (Ty.path "core::option::Option")
                                      []
                                      [ Ty.path "move_borrow_graph::references::RefID" ])
                                ],
                              [],
                              "into_iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::iter::traits::iterator::Iterator",
                                  Ty.apply
                                    (Ty.path "alloc::vec::into_iter::IntoIter")
                                    []
                                    [
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                      Ty.path "alloc::alloc::Global"
                                    ],
                                  [],
                                  "filter_map",
                                  [
                                    Ty.path "move_borrow_graph::references::RefID";
                                    Ty.function
                                      [
                                        Ty.tuple
                                          [
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                          ]
                                      ]
                                      (Ty.apply
                                        (Ty.path "core::option::Option")
                                        []
                                        [ Ty.path "move_borrow_graph::references::RefID" ])
                                  ]
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::iter::traits::collect::IntoIterator",
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      [],
                                      "into_iter",
                                      []
                                    |),
                                    [ M.read (| values |) ]
                                  |);
                                  M.closure
                                    (fun γ =>
                                      ltac:(M.monadic
                                        match γ with
                                        | [ α0 ] =>
                                          ltac:(M.monadic
                                            (M.match_operator (|
                                              M.alloc (| α0 |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let v := M.copy (| γ |) in
                                                    M.call_closure (|
                                                      M.get_associated_function (|
                                                        Ty.path
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue",
                                                        "ref_id",
                                                        []
                                                      |),
                                                      [ v ]
                                                    |)))
                                              ]
                                            |)))
                                        | _ => M.impossible "wrong number of arguments"
                                        end))
                                ]
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let iter := M.copy (| γ |) in
                              M.loop (|
                                ltac:(M.monadic
                                  (let~ _ :=
                                    M.match_operator (|
                                      M.alloc (|
                                        M.call_closure (|
                                          M.get_trait_method (|
                                            "core::iter::traits::iterator::Iterator",
                                            Ty.apply
                                              (Ty.path
                                                "core::iter::adapters::filter_map::FilterMap")
                                              []
                                              [
                                                Ty.apply
                                                  (Ty.path "alloc::vec::into_iter::IntoIter")
                                                  []
                                                  [
                                                    Ty.path
                                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                                    Ty.path "alloc::alloc::Global"
                                                  ];
                                                Ty.function
                                                  [
                                                    Ty.tuple
                                                      [
                                                        Ty.path
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                                      ]
                                                  ]
                                                  (Ty.apply
                                                    (Ty.path "core::option::Option")
                                                    []
                                                    [ Ty.path "move_borrow_graph::references::RefID"
                                                    ])
                                              ],
                                            [],
                                            "next",
                                            []
                                          |),
                                          [ iter ]
                                        |)
                                      |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let _ :=
                                              M.is_struct_tuple (|
                                                γ,
                                                "core::option::Option::None"
                                              |) in
                                            M.alloc (|
                                              M.never_to_any (| M.read (| M.break (||) |) |)
                                            |)));
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 :=
                                              M.SubPointer.get_struct_tuple_field (|
                                                γ,
                                                "core::option::Option::Some",
                                                0
                                              |) in
                                            let id := M.copy (| γ0_0 |) in
                                            M.match_operator (|
                                              M.alloc (| Value.Tuple [] |),
                                              [
                                                fun γ =>
                                                  ltac:(M.monadic
                                                    (let γ :=
                                                      M.use
                                                        (M.alloc (|
                                                          LogicalOp.and (|
                                                            M.call_closure (|
                                                              M.get_associated_function (|
                                                                Ty.apply
                                                                  (Ty.path
                                                                    "move_borrow_graph::graph::BorrowGraph")
                                                                  []
                                                                  [
                                                                    Ty.tuple [];
                                                                    Ty.path
                                                                      "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                                                  ],
                                                                "is_mutable",
                                                                []
                                                              |),
                                                              [
                                                                M.SubPointer.get_struct_record_field (|
                                                                  M.read (| self |),
                                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                  "borrow_graph"
                                                                |);
                                                                M.read (| id |)
                                                              ]
                                                            |),
                                                            ltac:(M.monadic
                                                              (UnOp.not (|
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path
                                                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                    "is_writable",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.read (| self |);
                                                                    M.read (| id |)
                                                                  ]
                                                                |)
                                                              |)))
                                                          |)
                                                        |)) in
                                                    let _ :=
                                                      M.is_constant_or_break_match (|
                                                        M.read (| γ |),
                                                        Value.Bool true
                                                      |) in
                                                    M.alloc (|
                                                      M.never_to_any (|
                                                        M.read (|
                                                          M.return_ (|
                                                            Value.StructTuple
                                                              "core::result::Result::Err"
                                                              [
                                                                M.call_closure (|
                                                                  M.get_associated_function (|
                                                                    Ty.path
                                                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                                                    "error",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.read (| self |);
                                                                    Value.StructTuple
                                                                      "move_core_types::vm_status::StatusCode::RET_BORROWED_MUTABLE_REFERENCE_ERROR"
                                                                      [];
                                                                    M.read (| offset |)
                                                                  ]
                                                                |)
                                                              ]
                                                          |)
                                                        |)
                                                      |)
                                                    |)));
                                                fun γ =>
                                                  ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                                              ]
                                            |)))
                                      ]
                                    |) in
                                  M.alloc (| Value.Tuple [] |)))
                              |)))
                        ]
                      |)) in
                  M.alloc (| Value.StructTuple "core::result::Result::Ok" [ Value.Tuple [] ] |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_ret : M.IsAssociatedFunction Self "ret" ret.
      
      (*
          pub fn construct_canonical_state(&self) -> Self {
              let mut id_map = BTreeMap::new();
              id_map.insert(self.frame_root(), self.frame_root());
              let locals = self
                  .locals
                  .iter()
                  .enumerate()
                  .map(|(local, value)| match value {
                      AbstractValue::Reference(old_id) => {
                          let new_id = RefID::new(local);
                          id_map.insert( *old_id, new_id);
                          AbstractValue::Reference(new_id)
                      }
                      AbstractValue::NonReference => AbstractValue::NonReference,
                  })
                  .collect::<Vec<_>>();
              assert!(self.locals.len() == locals.len());
              let mut borrow_graph = self.borrow_graph.clone();
              borrow_graph.remap_refs(&id_map);
              let canonical_state = AbstractState {
                  locals,
                  borrow_graph,
                  current_function: self.current_function,
                  next_id: self.locals.len() + 1,
              };
              assert!(canonical_state.is_canonical());
              canonical_state
          }
      *)
      Definition construct_canonical_state
          (ε : list Value.t)
          (τ : list Ty.t)
          (α : list Value.t)
          : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            M.read (|
              let~ id_map :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::collections::btree::map::BTreeMap")
                        []
                        [
                          Ty.path "move_borrow_graph::references::RefID";
                          Ty.path "move_borrow_graph::references::RefID";
                          Ty.path "alloc::alloc::Global"
                        ],
                      "new",
                      []
                    |),
                    []
                  |)
                |) in
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::collections::btree::map::BTreeMap")
                        []
                        [
                          Ty.path "move_borrow_graph::references::RefID";
                          Ty.path "move_borrow_graph::references::RefID";
                          Ty.path "alloc::alloc::Global"
                        ],
                      "insert",
                      []
                    |),
                    [
                      id_map;
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "frame_root",
                          []
                        |),
                        [ M.read (| self |) ]
                      |);
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "frame_root",
                          []
                        |),
                        [ M.read (| self |) ]
                      |)
                    ]
                  |)
                |) in
              let~ locals :=
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::iter::traits::iterator::Iterator",
                      Ty.apply
                        (Ty.path "core::iter::adapters::map::Map")
                        []
                        [
                          Ty.apply
                            (Ty.path "core::iter::adapters::enumerate::Enumerate")
                            []
                            [
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ]
                            ];
                          Ty.function
                            [
                              Ty.tuple
                                [
                                  Ty.tuple
                                    [
                                      Ty.path "usize";
                                      Ty.apply
                                        (Ty.path "&")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                        ]
                                    ]
                                ]
                            ]
                            (Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue")
                        ],
                      [],
                      "collect",
                      [
                        Ty.apply
                          (Ty.path "alloc::vec::Vec")
                          []
                          [
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                            Ty.path "alloc::alloc::Global"
                          ]
                      ]
                    |),
                    [
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          Ty.apply
                            (Ty.path "core::iter::adapters::enumerate::Enumerate")
                            []
                            [
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ]
                            ],
                          [],
                          "map",
                          [
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                            Ty.function
                              [
                                Ty.tuple
                                  [
                                    Ty.tuple
                                      [
                                        Ty.path "usize";
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                          ]
                                      ]
                                  ]
                              ]
                              (Ty.path
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue")
                          ]
                        |),
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ],
                              [],
                              "enumerate",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    []
                                    [
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                    ],
                                  "iter",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::deref::Deref",
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      [],
                                      "deref",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "locals"
                                      |)
                                    ]
                                  |)
                                ]
                              |)
                            ]
                          |);
                          M.closure
                            (fun γ =>
                              ltac:(M.monadic
                                match γ with
                                | [ α0 ] =>
                                  ltac:(M.monadic
                                    (M.match_operator (|
                                      M.alloc (| α0 |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                            let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                            let local := M.copy (| γ0_0 |) in
                                            let value := M.copy (| γ0_1 |) in
                                            M.read (|
                                              M.match_operator (|
                                                value,
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ := M.read (| γ |) in
                                                      let γ1_0 :=
                                                        M.SubPointer.get_struct_tuple_field (|
                                                          γ,
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                                          0
                                                        |) in
                                                      let old_id := M.alloc (| γ1_0 |) in
                                                      let~ new_id :=
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.path
                                                                "move_borrow_graph::references::RefID",
                                                              "new",
                                                              []
                                                            |),
                                                            [ M.read (| local |) ]
                                                          |)
                                                        |) in
                                                      let~ _ :=
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path
                                                                  "alloc::collections::btree::map::BTreeMap")
                                                                []
                                                                [
                                                                  Ty.path
                                                                    "move_borrow_graph::references::RefID";
                                                                  Ty.path
                                                                    "move_borrow_graph::references::RefID";
                                                                  Ty.path "alloc::alloc::Global"
                                                                ],
                                                              "insert",
                                                              []
                                                            |),
                                                            [
                                                              id_map;
                                                              M.read (| M.read (| old_id |) |);
                                                              M.read (| new_id |)
                                                            ]
                                                          |)
                                                        |) in
                                                      M.alloc (|
                                                        Value.StructTuple
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference"
                                                          [ M.read (| new_id |) ]
                                                      |)));
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ := M.read (| γ |) in
                                                      let _ :=
                                                        M.is_struct_tuple (|
                                                          γ,
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                                                        |) in
                                                      M.alloc (|
                                                        Value.StructTuple
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                                                          []
                                                      |)))
                                                ]
                                              |)
                                            |)))
                                      ]
                                    |)))
                                | _ => M.impossible "wrong number of arguments"
                                end))
                        ]
                      |)
                    ]
                  |)
                |) in
              let~ _ :=
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              UnOp.not (|
                                BinOp.eq (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      "len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "locals"
                                      |)
                                    ]
                                  |),
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      "len",
                                      []
                                    |),
                                    [ locals ]
                                  |)
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.never_to_any (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic", [] |),
                              [
                                M.read (|
                                  Value.String "assertion failed: self.locals.len() == locals.len()"
                                |)
                              ]
                            |)
                          |)
                        |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |) in
              let~ borrow_graph :=
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |)
                    ]
                  |)
                |) in
              let~ _ :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      "remap_refs",
                      []
                    |),
                    [ borrow_graph; id_map ]
                  |)
                |) in
              let~ canonical_state :=
                M.alloc (|
                  Value.StructRecord
                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState"
                    [
                      ("locals", M.read (| locals |));
                      ("borrow_graph", M.read (| borrow_graph |));
                      ("current_function",
                        M.read (|
                          M.SubPointer.get_struct_record_field (|
                            M.read (| self |),
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                            "current_function"
                          |)
                        |));
                      ("next_id",
                        BinOp.Wrap.add (|
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "alloc::vec::Vec")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                  Ty.path "alloc::alloc::Global"
                                ],
                              "len",
                              []
                            |),
                            [
                              M.SubPointer.get_struct_record_field (|
                                M.read (| self |),
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                "locals"
                              |)
                            ]
                          |),
                          Value.Integer IntegerKind.Usize 1
                        |))
                    ]
                |) in
              let~ _ :=
                M.match_operator (|
                  M.alloc (| Value.Tuple [] |),
                  [
                    fun γ =>
                      ltac:(M.monadic
                        (let γ :=
                          M.use
                            (M.alloc (|
                              UnOp.not (|
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.path
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                    "is_canonical",
                                    []
                                  |),
                                  [ canonical_state ]
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.never_to_any (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic", [] |),
                              [
                                M.read (|
                                  Value.String "assertion failed: canonical_state.is_canonical()"
                                |)
                              ]
                            |)
                          |)
                        |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |) in
              canonical_state
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_construct_canonical_state :
        M.IsAssociatedFunction Self "construct_canonical_state" construct_canonical_state.
      
      (*
          fn all_immutable(&self, borrows: &BTreeMap<RefID, ()>) -> bool {
              !borrows.keys().any(|x| self.borrow_graph.is_mutable( *x))
          }
      *)
      Definition all_immutable (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; borrows ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let borrows := M.alloc (| borrows |) in
            UnOp.not (|
              M.call_closure (|
                M.get_trait_method (|
                  "core::iter::traits::iterator::Iterator",
                  Ty.apply
                    (Ty.path "alloc::collections::btree::map::Keys")
                    []
                    [ Ty.path "move_borrow_graph::references::RefID"; Ty.tuple [] ],
                  [],
                  "any",
                  [
                    Ty.function
                      [
                        Ty.tuple
                          [
                            Ty.apply
                              (Ty.path "&")
                              []
                              [ Ty.path "move_borrow_graph::references::RefID" ]
                          ]
                      ]
                      (Ty.path "bool")
                  ]
                |),
                [
                  M.alloc (|
                    M.call_closure (|
                      M.get_associated_function (|
                        Ty.apply
                          (Ty.path "alloc::collections::btree::map::BTreeMap")
                          []
                          [
                            Ty.path "move_borrow_graph::references::RefID";
                            Ty.tuple [];
                            Ty.path "alloc::alloc::Global"
                          ],
                        "keys",
                        []
                      |),
                      [ M.read (| borrows |) ]
                    |)
                  |);
                  M.closure
                    (fun γ =>
                      ltac:(M.monadic
                        match γ with
                        | [ α0 ] =>
                          ltac:(M.monadic
                            (M.match_operator (|
                              M.alloc (| α0 |),
                              [
                                fun γ =>
                                  ltac:(M.monadic
                                    (let x := M.copy (| γ |) in
                                    M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply
                                          (Ty.path "move_borrow_graph::graph::BorrowGraph")
                                          []
                                          [
                                            Ty.tuple [];
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                          ],
                                        "is_mutable",
                                        []
                                      |),
                                      [
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                          "borrow_graph"
                                        |);
                                        M.read (| M.read (| x |) |)
                                      ]
                                    |)))
                              ]
                            |)))
                        | _ => M.impossible "wrong number of arguments"
                        end))
                ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_all_immutable :
        M.IsAssociatedFunction Self "all_immutable" all_immutable.
      
      (*
          fn is_canonical(&self) -> bool {
              self.locals.len() + 1 == self.next_id
                  && self.locals.iter().enumerate().all(|(local, value)| {
                      value
                          .ref_id()
                          .map(|id| RefID::new(local) == id)
                          .unwrap_or(true)
                  })
          }
      *)
      Definition is_canonical (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            LogicalOp.and (|
              BinOp.eq (|
                BinOp.Wrap.add (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "alloc::vec::Vec")
                        []
                        [
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                          Ty.path "alloc::alloc::Global"
                        ],
                      "len",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "locals"
                      |)
                    ]
                  |),
                  Value.Integer IntegerKind.Usize 1
                |),
                M.read (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "next_id"
                  |)
                |)
              |),
              ltac:(M.monadic
                (M.call_closure (|
                  M.get_trait_method (|
                    "core::iter::traits::iterator::Iterator",
                    Ty.apply
                      (Ty.path "core::iter::adapters::enumerate::Enumerate")
                      []
                      [
                        Ty.apply
                          (Ty.path "core::slice::iter::Iter")
                          []
                          [
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                          ]
                      ],
                    [],
                    "all",
                    [
                      Ty.function
                        [
                          Ty.tuple
                            [
                              Ty.tuple
                                [
                                  Ty.path "usize";
                                  Ty.apply
                                    (Ty.path "&")
                                    []
                                    [
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                    ]
                                ]
                            ]
                        ]
                        (Ty.path "bool")
                    ]
                  |),
                  [
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          Ty.apply
                            (Ty.path "core::slice::iter::Iter")
                            []
                            [
                              Ty.path
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                            ],
                          [],
                          "enumerate",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_associated_function (|
                              Ty.apply
                                (Ty.path "slice")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ],
                              "iter",
                              []
                            |),
                            [
                              M.call_closure (|
                                M.get_trait_method (|
                                  "core::ops::deref::Deref",
                                  Ty.apply
                                    (Ty.path "alloc::vec::Vec")
                                    []
                                    [
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                      Ty.path "alloc::alloc::Global"
                                    ],
                                  [],
                                  "deref",
                                  []
                                |),
                                [
                                  M.SubPointer.get_struct_record_field (|
                                    M.read (| self |),
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                    "locals"
                                  |)
                                ]
                              |)
                            ]
                          |)
                        ]
                      |)
                    |);
                    M.closure
                      (fun γ =>
                        ltac:(M.monadic
                          match γ with
                          | [ α0 ] =>
                            ltac:(M.monadic
                              (M.match_operator (|
                                M.alloc (| α0 |),
                                [
                                  fun γ =>
                                    ltac:(M.monadic
                                      (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                      let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                      let local := M.copy (| γ0_0 |) in
                                      let value := M.copy (| γ0_1 |) in
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "core::option::Option")
                                            []
                                            [ Ty.path "bool" ],
                                          "unwrap_or",
                                          []
                                        |),
                                        [
                                          M.call_closure (|
                                            M.get_associated_function (|
                                              Ty.apply
                                                (Ty.path "core::option::Option")
                                                []
                                                [ Ty.path "move_borrow_graph::references::RefID" ],
                                              "map",
                                              [
                                                Ty.path "bool";
                                                Ty.function
                                                  [
                                                    Ty.tuple
                                                      [
                                                        Ty.path
                                                          "move_borrow_graph::references::RefID"
                                                      ]
                                                  ]
                                                  (Ty.path "bool")
                                              ]
                                            |),
                                            [
                                              M.call_closure (|
                                                M.get_associated_function (|
                                                  Ty.path
                                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue",
                                                  "ref_id",
                                                  []
                                                |),
                                                [ M.read (| value |) ]
                                              |);
                                              M.closure
                                                (fun γ =>
                                                  ltac:(M.monadic
                                                    match γ with
                                                    | [ α0 ] =>
                                                      ltac:(M.monadic
                                                        (M.match_operator (|
                                                          M.alloc (| α0 |),
                                                          [
                                                            fun γ =>
                                                              ltac:(M.monadic
                                                                (let id := M.copy (| γ |) in
                                                                M.call_closure (|
                                                                  M.get_trait_method (|
                                                                    "core::cmp::PartialEq",
                                                                    Ty.path
                                                                      "move_borrow_graph::references::RefID",
                                                                    [
                                                                      Ty.path
                                                                        "move_borrow_graph::references::RefID"
                                                                    ],
                                                                    "eq",
                                                                    []
                                                                  |),
                                                                  [
                                                                    M.alloc (|
                                                                      M.call_closure (|
                                                                        M.get_associated_function (|
                                                                          Ty.path
                                                                            "move_borrow_graph::references::RefID",
                                                                          "new",
                                                                          []
                                                                        |),
                                                                        [ M.read (| local |) ]
                                                                      |)
                                                                    |);
                                                                    id
                                                                  ]
                                                                |)))
                                                          ]
                                                        |)))
                                                    | _ => M.impossible "wrong number of arguments"
                                                    end))
                                            ]
                                          |);
                                          Value.Bool true
                                        ]
                                      |)))
                                ]
                              |)))
                          | _ => M.impossible "wrong number of arguments"
                          end))
                  ]
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_is_canonical :
        M.IsAssociatedFunction Self "is_canonical" is_canonical.
      
      (*
          pub fn join_(&self, other: &Self) -> Self {
              assert!(self.current_function == other.current_function);
              assert!(self.is_canonical() && other.is_canonical());
              assert!(self.next_id == other.next_id);
              assert!(self.locals.len() == other.locals.len());
              let mut self_graph = self.borrow_graph.clone();
              let mut other_graph = other.borrow_graph.clone();
              let locals = self
                  .locals
                  .iter()
                  .zip(&other.locals)
                  .map(|(self_value, other_value)| {
                      match (self_value, other_value) {
                          (AbstractValue::Reference(id), AbstractValue::NonReference) => {
                              self_graph.release( *id);
                              AbstractValue::NonReference
                          }
                          (AbstractValue::NonReference, AbstractValue::Reference(id)) => {
                              other_graph.release( *id);
                              AbstractValue::NonReference
                          }
                          // The local has a value on each side, add it to the state
                          (v1, v2) => {
                              assert!(v1 == v2);
                              *v1
                          }
                      }
                  })
                  .collect();
      
              let borrow_graph = self_graph.join(&other_graph);
              let current_function = self.current_function;
              let next_id = self.next_id;
      
              Self {
                  current_function,
                  locals,
                  borrow_graph,
                  next_id,
              }
          }
      *)
      Definition join_ (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [], [ self; other ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let other := M.alloc (| other |) in
            M.read (|
              let~ _ :=
                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 (|
                                    "core::cmp::PartialEq",
                                    Ty.apply
                                      (Ty.path "core::option::Option")
                                      []
                                      [
                                        Ty.path
                                          "move_binary_format::file_format::FunctionDefinitionIndex"
                                      ],
                                    [
                                      Ty.apply
                                        (Ty.path "core::option::Option")
                                        []
                                        [
                                          Ty.path
                                            "move_binary_format::file_format::FunctionDefinitionIndex"
                                        ]
                                    ],
                                    "eq",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                      "current_function"
                                    |);
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| other |),
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                      "current_function"
                                    |)
                                  ]
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.never_to_any (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic", [] |),
                              [
                                M.read (|
                                  Value.String
                                    "assertion failed: self.current_function == other.current_function"
                                |)
                              ]
                            |)
                          |)
                        |)));
                    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 (|
                                LogicalOp.and (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                      "is_canonical",
                                      []
                                    |),
                                    [ M.read (| self |) ]
                                  |),
                                  ltac:(M.monadic
                                    (M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "is_canonical",
                                        []
                                      |),
                                      [ M.read (| other |) ]
                                    |)))
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.never_to_any (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic", [] |),
                              [
                                M.read (|
                                  Value.String
                                    "assertion failed: self.is_canonical() && other.is_canonical()"
                                |)
                              ]
                            |)
                          |)
                        |)));
                    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 (|
                                BinOp.eq (|
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                      "next_id"
                                    |)
                                  |),
                                  M.read (|
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| other |),
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                      "next_id"
                                    |)
                                  |)
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.never_to_any (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic", [] |),
                              [
                                M.read (|
                                  Value.String "assertion failed: self.next_id == other.next_id"
                                |)
                              ]
                            |)
                          |)
                        |)));
                    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 (|
                                BinOp.eq (|
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      "len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "locals"
                                      |)
                                    ]
                                  |),
                                  M.call_closure (|
                                    M.get_associated_function (|
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      "len",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| other |),
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "locals"
                                      |)
                                    ]
                                  |)
                                |)
                              |)
                            |)) in
                        let _ :=
                          M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                        M.alloc (|
                          M.never_to_any (|
                            M.call_closure (|
                              M.get_function (| "core::panicking::panic", [] |),
                              [
                                M.read (|
                                  Value.String
                                    "assertion failed: self.locals.len() == other.locals.len()"
                                |)
                              ]
                            |)
                          |)
                        |)));
                    fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                  ]
                |) in
              let~ self_graph :=
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| self |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |)
                    ]
                  |)
                |) in
              let~ other_graph :=
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::clone::Clone",
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      [],
                      "clone",
                      []
                    |),
                    [
                      M.SubPointer.get_struct_record_field (|
                        M.read (| other |),
                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                        "borrow_graph"
                      |)
                    ]
                  |)
                |) in
              let~ locals :=
                M.alloc (|
                  M.call_closure (|
                    M.get_trait_method (|
                      "core::iter::traits::iterator::Iterator",
                      Ty.apply
                        (Ty.path "core::iter::adapters::map::Map")
                        []
                        [
                          Ty.apply
                            (Ty.path "core::iter::adapters::zip::Zip")
                            []
                            [
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ];
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ]
                            ];
                          Ty.function
                            [
                              Ty.tuple
                                [
                                  Ty.tuple
                                    [
                                      Ty.apply
                                        (Ty.path "&")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                        ];
                                      Ty.apply
                                        (Ty.path "&")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                        ]
                                    ]
                                ]
                            ]
                            (Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue")
                        ],
                      [],
                      "collect",
                      [
                        Ty.apply
                          (Ty.path "alloc::vec::Vec")
                          []
                          [
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                            Ty.path "alloc::alloc::Global"
                          ]
                      ]
                    |),
                    [
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          Ty.apply
                            (Ty.path "core::iter::adapters::zip::Zip")
                            []
                            [
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ];
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ]
                            ],
                          [],
                          "map",
                          [
                            Ty.path
                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                            Ty.function
                              [
                                Ty.tuple
                                  [
                                    Ty.tuple
                                      [
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                          ];
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                          ]
                                      ]
                                  ]
                              ]
                              (Ty.path
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue")
                          ]
                        |),
                        [
                          M.call_closure (|
                            M.get_trait_method (|
                              "core::iter::traits::iterator::Iterator",
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ],
                              [],
                              "zip",
                              [
                                Ty.apply
                                  (Ty.path "&")
                                  []
                                  [
                                    Ty.apply
                                      (Ty.path "alloc::vec::Vec")
                                      []
                                      [
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                        Ty.path "alloc::alloc::Global"
                                      ]
                                  ]
                              ]
                            |),
                            [
                              M.call_closure (|
                                M.get_associated_function (|
                                  Ty.apply
                                    (Ty.path "slice")
                                    []
                                    [
                                      Ty.path
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                    ],
                                  "iter",
                                  []
                                |),
                                [
                                  M.call_closure (|
                                    M.get_trait_method (|
                                      "core::ops::deref::Deref",
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                          Ty.path "alloc::alloc::Global"
                                        ],
                                      [],
                                      "deref",
                                      []
                                    |),
                                    [
                                      M.SubPointer.get_struct_record_field (|
                                        M.read (| self |),
                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "locals"
                                      |)
                                    ]
                                  |)
                                ]
                              |);
                              M.SubPointer.get_struct_record_field (|
                                M.read (| other |),
                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                "locals"
                              |)
                            ]
                          |);
                          M.closure
                            (fun γ =>
                              ltac:(M.monadic
                                match γ with
                                | [ α0 ] =>
                                  ltac:(M.monadic
                                    (M.match_operator (|
                                      M.alloc (| α0 |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                            let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                            let self_value := M.copy (| γ0_0 |) in
                                            let other_value := M.copy (| γ0_1 |) in
                                            M.read (|
                                              M.match_operator (|
                                                M.alloc (|
                                                  Value.Tuple
                                                    [
                                                      M.read (| self_value |);
                                                      M.read (| other_value |)
                                                    ]
                                                |),
                                                [
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ0_0 :=
                                                        M.SubPointer.get_tuple_field (| γ, 0 |) in
                                                      let γ0_1 :=
                                                        M.SubPointer.get_tuple_field (| γ, 1 |) in
                                                      let γ0_0 := M.read (| γ0_0 |) in
                                                      let γ2_0 :=
                                                        M.SubPointer.get_struct_tuple_field (|
                                                          γ0_0,
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                                          0
                                                        |) in
                                                      let id := M.alloc (| γ2_0 |) in
                                                      let γ0_1 := M.read (| γ0_1 |) in
                                                      let _ :=
                                                        M.is_struct_tuple (|
                                                          γ0_1,
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                                                        |) in
                                                      let~ _ :=
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path
                                                                  "move_borrow_graph::graph::BorrowGraph")
                                                                []
                                                                [
                                                                  Ty.tuple [];
                                                                  Ty.path
                                                                    "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                                                ],
                                                              "release",
                                                              []
                                                            |),
                                                            [
                                                              self_graph;
                                                              M.read (| M.read (| id |) |)
                                                            ]
                                                          |)
                                                        |) in
                                                      M.alloc (|
                                                        Value.StructTuple
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                                                          []
                                                      |)));
                                                  fun γ =>
                                                    ltac:(M.monadic
                                                      (let γ0_0 :=
                                                        M.SubPointer.get_tuple_field (| γ, 0 |) in
                                                      let γ0_1 :=
                                                        M.SubPointer.get_tuple_field (| γ, 1 |) in
                                                      let γ0_0 := M.read (| γ0_0 |) in
                                                      let _ :=
                                                        M.is_struct_tuple (|
                                                          γ0_0,
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                                                        |) in
                                                      let γ0_1 := M.read (| γ0_1 |) in
                                                      let γ2_0 :=
                                                        M.SubPointer.get_struct_tuple_field (|
                                                          γ0_1,
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::Reference",
                                                          0
                                                        |) in
                                                      let id := M.alloc (| γ2_0 |) in
                                                      let~ _ :=
                                                        M.alloc (|
                                                          M.call_closure (|
                                                            M.get_associated_function (|
                                                              Ty.apply
                                                                (Ty.path
                                                                  "move_borrow_graph::graph::BorrowGraph")
                                                                []
                                                                [
                                                                  Ty.tuple [];
                                                                  Ty.path
                                                                    "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                                                ],
                                                              "release",
                                                              []
                                                            |),
                                                            [
                                                              other_graph;
                                                              M.read (| M.read (| id |) |)
                                                            ]
                                                          |)
                                                        |) in
                                                      M.alloc (|
                                                        Value.StructTuple
                                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue::NonReference"
                                                          []
                                                      |)));
                                                  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 v1 := M.copy (| γ0_0 |) in
                                                      let v2 := M.copy (| γ0_1 |) 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_trait_method (|
                                                                            "core::cmp::PartialEq",
                                                                            Ty.apply
                                                                              (Ty.path "&")
                                                                              []
                                                                              [
                                                                                Ty.path
                                                                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                                                              ],
                                                                            [
                                                                              Ty.apply
                                                                                (Ty.path "&")
                                                                                []
                                                                                [
                                                                                  Ty.path
                                                                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                                                                ]
                                                                            ],
                                                                            "eq",
                                                                            []
                                                                          |),
                                                                          [ v1; v2 ]
                                                                        |)
                                                                      |)
                                                                    |)) in
                                                                let _ :=
                                                                  M.is_constant_or_break_match (|
                                                                    M.read (| γ |),
                                                                    Value.Bool true
                                                                  |) in
                                                                M.alloc (|
                                                                  M.never_to_any (|
                                                                    M.call_closure (|
                                                                      M.get_function (|
                                                                        "core::panicking::panic",
                                                                        []
                                                                      |),
                                                                      [
                                                                        M.read (|
                                                                          Value.String
                                                                            "assertion failed: v1 == v2"
                                                                        |)
                                                                      ]
                                                                    |)
                                                                  |)
                                                                |)));
                                                            fun γ =>
                                                              ltac:(M.monadic
                                                                (M.alloc (| Value.Tuple [] |)))
                                                          ]
                                                        |) in
                                                      M.read (| v1 |)))
                                                ]
                                              |)
                                            |)))
                                      ]
                                    |)))
                                | _ => M.impossible "wrong number of arguments"
                                end))
                        ]
                      |)
                    ]
                  |)
                |) in
              let~ borrow_graph :=
                M.alloc (|
                  M.call_closure (|
                    M.get_associated_function (|
                      Ty.apply
                        (Ty.path "move_borrow_graph::graph::BorrowGraph")
                        []
                        [
                          Ty.tuple [];
                          Ty.path "move_bytecode_verifier::reference_safety::abstract_state::Label"
                        ],
                      "join",
                      []
                    |),
                    [ self_graph; other_graph ]
                  |)
                |) in
              let~ current_function :=
                M.copy (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "current_function"
                  |)
                |) in
              let~ next_id :=
                M.copy (|
                  M.SubPointer.get_struct_record_field (|
                    M.read (| self |),
                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                    "next_id"
                  |)
                |) in
              M.alloc (|
                Value.StructRecord
                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState"
                  [
                    ("current_function", M.read (| current_function |));
                    ("locals", M.read (| locals |));
                    ("borrow_graph", M.read (| borrow_graph |));
                    ("next_id", M.read (| next_id |))
                  ]
              |)
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom AssociatedFunction_join_ : M.IsAssociatedFunction Self "join_" join_.
    End Impl_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
    
    Module Impl_move_bytecode_verifier_absint_AbstractDomain_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
      Definition Self : Ty.t :=
        Ty.path "move_bytecode_verifier::reference_safety::abstract_state::AbstractState".
      
      (*
          fn join(
              &mut self,
              state: &AbstractState,
              meter: &mut (impl Meter + ?Sized),
          ) -> PartialVMResult<JoinResult> {
              let joined = Self::join_(self, state);
              assert!(joined.is_canonical());
              assert!(self.locals.len() == joined.locals.len());
              meter.add(Scope::Function, JOIN_BASE_COST)?;
              meter.add_items(Scope::Function, JOIN_PER_LOCAL_COST, self.locals.len())?;
              meter.add_items(
                  Scope::Function,
                  JOIN_PER_GRAPH_ITEM_COST,
                  self.borrow_graph.graph_size(),
              )?;
              let locals_unchanged = self
                  .locals
                  .iter()
                  .zip(&joined.locals)
                  .all(|(self_value, joined_value)| self_value == joined_value);
              // locals unchanged and borrow graph covered, return unchanged
              // else mark as changed and update the state
              if locals_unchanged && self.borrow_graph.leq(&joined.borrow_graph) {
                  Ok(JoinResult::Unchanged)
              } else {
                  *self = joined;
                  Ok(JoinResult::Changed)
              }
          }
      *)
      Definition join (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        match ε, τ, α with
        | [], [ impl_Meter__plus___Sized ], [ self; state; meter ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let state := M.alloc (| state |) in
            let meter := M.alloc (| meter |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ joined :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.path
                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                          "join_",
                          []
                        |),
                        [ M.read (| self |); M.read (| state |) ]
                      |)
                    |) 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
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                        "is_canonical",
                                        []
                                      |),
                                      [ joined ]
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.call_closure (|
                                  M.get_function (| "core::panicking::panic", [] |),
                                  [
                                    M.read (|
                                      Value.String "assertion failed: joined.is_canonical()"
                                    |)
                                  ]
                                |)
                              |)
                            |)));
                        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 (|
                                    BinOp.eq (|
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "alloc::vec::Vec")
                                            []
                                            [
                                              Ty.path
                                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                              Ty.path "alloc::alloc::Global"
                                            ],
                                          "len",
                                          []
                                        |),
                                        [
                                          M.SubPointer.get_struct_record_field (|
                                            M.read (| self |),
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "locals"
                                          |)
                                        ]
                                      |),
                                      M.call_closure (|
                                        M.get_associated_function (|
                                          Ty.apply
                                            (Ty.path "alloc::vec::Vec")
                                            []
                                            [
                                              Ty.path
                                                "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                              Ty.path "alloc::alloc::Global"
                                            ],
                                          "len",
                                          []
                                        |),
                                        [
                                          M.SubPointer.get_struct_record_field (|
                                            joined,
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                            "locals"
                                          |)
                                        ]
                                      |)
                                    |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.call_closure (|
                                  M.get_function (| "core::panicking::panic", [] |),
                                  [
                                    M.read (|
                                      Value.String
                                        "assertion failed: self.locals.len() == joined.locals.len()"
                                    |)
                                  ]
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::try_trait::Try",
                            Ty.apply
                              (Ty.path "core::result::Result")
                              []
                              [ Ty.tuple []; Ty.path "move_binary_format::errors::PartialVMError" ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "move_bytecode_verifier_meter::Meter",
                                impl_Meter__plus___Sized,
                                [],
                                "add",
                                []
                              |),
                              [
                                M.read (| meter |);
                                Value.StructTuple
                                  "move_bytecode_verifier_meter::Scope::Function"
                                  [];
                                M.read (|
                                  M.get_constant (|
                                    "move_bytecode_verifier::reference_safety::abstract_state::JOIN_BASE_COST"
                                  |)
                                |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Break",
                                0
                              |) in
                            let residual := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::FromResidual",
                                        Ty.apply
                                          (Ty.path "core::result::Result")
                                          []
                                          [
                                            Ty.path "move_bytecode_verifier::absint::JoinResult";
                                            Ty.path "move_binary_format::errors::PartialVMError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            []
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "move_binary_format::errors::PartialVMError"
                                            ]
                                        ],
                                        "from_residual",
                                        []
                                      |),
                                      [ M.read (| residual |) ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Continue",
                                0
                              |) in
                            let val := M.copy (| γ0_0 |) in
                            val))
                      ]
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::try_trait::Try",
                            Ty.apply
                              (Ty.path "core::result::Result")
                              []
                              [ Ty.tuple []; Ty.path "move_binary_format::errors::PartialVMError" ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "move_bytecode_verifier_meter::Meter",
                                impl_Meter__plus___Sized,
                                [],
                                "add_items",
                                []
                              |),
                              [
                                M.read (| meter |);
                                Value.StructTuple
                                  "move_bytecode_verifier_meter::Scope::Function"
                                  [];
                                M.read (|
                                  M.get_constant (|
                                    "move_bytecode_verifier::reference_safety::abstract_state::JOIN_PER_LOCAL_COST"
                                  |)
                                |);
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply
                                      (Ty.path "alloc::vec::Vec")
                                      []
                                      [
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                        Ty.path "alloc::alloc::Global"
                                      ],
                                    "len",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                      "locals"
                                    |)
                                  ]
                                |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Break",
                                0
                              |) in
                            let residual := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::FromResidual",
                                        Ty.apply
                                          (Ty.path "core::result::Result")
                                          []
                                          [
                                            Ty.path "move_bytecode_verifier::absint::JoinResult";
                                            Ty.path "move_binary_format::errors::PartialVMError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            []
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "move_binary_format::errors::PartialVMError"
                                            ]
                                        ],
                                        "from_residual",
                                        []
                                      |),
                                      [ M.read (| residual |) ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Continue",
                                0
                              |) in
                            let val := M.copy (| γ0_0 |) in
                            val))
                      ]
                    |) in
                  let~ _ :=
                    M.match_operator (|
                      M.alloc (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "core::ops::try_trait::Try",
                            Ty.apply
                              (Ty.path "core::result::Result")
                              []
                              [ Ty.tuple []; Ty.path "move_binary_format::errors::PartialVMError" ],
                            [],
                            "branch",
                            []
                          |),
                          [
                            M.call_closure (|
                              M.get_trait_method (|
                                "move_bytecode_verifier_meter::Meter",
                                impl_Meter__plus___Sized,
                                [],
                                "add_items",
                                []
                              |),
                              [
                                M.read (| meter |);
                                Value.StructTuple
                                  "move_bytecode_verifier_meter::Scope::Function"
                                  [];
                                M.read (|
                                  M.get_constant (|
                                    "move_bytecode_verifier::reference_safety::abstract_state::JOIN_PER_GRAPH_ITEM_COST"
                                  |)
                                |);
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply
                                      (Ty.path "move_borrow_graph::graph::BorrowGraph")
                                      []
                                      [
                                        Ty.tuple [];
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                      ],
                                    "graph_size",
                                    []
                                  |),
                                  [
                                    M.SubPointer.get_struct_record_field (|
                                      M.read (| self |),
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                      "borrow_graph"
                                    |)
                                  ]
                                |)
                              ]
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Break",
                                0
                              |) in
                            let residual := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::try_trait::FromResidual",
                                        Ty.apply
                                          (Ty.path "core::result::Result")
                                          []
                                          [
                                            Ty.path "move_bytecode_verifier::absint::JoinResult";
                                            Ty.path "move_binary_format::errors::PartialVMError"
                                          ],
                                        [
                                          Ty.apply
                                            (Ty.path "core::result::Result")
                                            []
                                            [
                                              Ty.path "core::convert::Infallible";
                                              Ty.path "move_binary_format::errors::PartialVMError"
                                            ]
                                        ],
                                        "from_residual",
                                        []
                                      |),
                                      [ M.read (| residual |) ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::ops::control_flow::ControlFlow::Continue",
                                0
                              |) in
                            let val := M.copy (| γ0_0 |) in
                            val))
                      ]
                    |) in
                  let~ locals_unchanged :=
                    M.alloc (|
                      M.call_closure (|
                        M.get_trait_method (|
                          "core::iter::traits::iterator::Iterator",
                          Ty.apply
                            (Ty.path "core::iter::adapters::zip::Zip")
                            []
                            [
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ];
                              Ty.apply
                                (Ty.path "core::slice::iter::Iter")
                                []
                                [
                                  Ty.path
                                    "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                ]
                            ],
                          [],
                          "all",
                          [
                            Ty.function
                              [
                                Ty.tuple
                                  [
                                    Ty.tuple
                                      [
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                          ];
                                        Ty.apply
                                          (Ty.path "&")
                                          []
                                          [
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                          ]
                                      ]
                                  ]
                              ]
                              (Ty.path "bool")
                          ]
                        |),
                        [
                          M.alloc (|
                            M.call_closure (|
                              M.get_trait_method (|
                                "core::iter::traits::iterator::Iterator",
                                Ty.apply
                                  (Ty.path "core::slice::iter::Iter")
                                  []
                                  [
                                    Ty.path
                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                  ],
                                [],
                                "zip",
                                [
                                  Ty.apply
                                    (Ty.path "&")
                                    []
                                    [
                                      Ty.apply
                                        (Ty.path "alloc::vec::Vec")
                                        []
                                        [
                                          Ty.path
                                            "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                          Ty.path "alloc::alloc::Global"
                                        ]
                                    ]
                                ]
                              |),
                              [
                                M.call_closure (|
                                  M.get_associated_function (|
                                    Ty.apply
                                      (Ty.path "slice")
                                      []
                                      [
                                        Ty.path
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                      ],
                                    "iter",
                                    []
                                  |),
                                  [
                                    M.call_closure (|
                                      M.get_trait_method (|
                                        "core::ops::deref::Deref",
                                        Ty.apply
                                          (Ty.path "alloc::vec::Vec")
                                          []
                                          [
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue";
                                            Ty.path "alloc::alloc::Global"
                                          ],
                                        [],
                                        "deref",
                                        []
                                      |),
                                      [
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                          "locals"
                                        |)
                                      ]
                                    |)
                                  ]
                                |);
                                M.SubPointer.get_struct_record_field (|
                                  joined,
                                  "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                  "locals"
                                |)
                              ]
                            |)
                          |);
                          M.closure
                            (fun γ =>
                              ltac:(M.monadic
                                match γ with
                                | [ α0 ] =>
                                  ltac:(M.monadic
                                    (M.match_operator (|
                                      M.alloc (| α0 |),
                                      [
                                        fun γ =>
                                          ltac:(M.monadic
                                            (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                                            let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                                            let self_value := M.copy (| γ0_0 |) in
                                            let joined_value := M.copy (| γ0_1 |) in
                                            M.call_closure (|
                                              M.get_trait_method (|
                                                "core::cmp::PartialEq",
                                                Ty.apply
                                                  (Ty.path "&")
                                                  []
                                                  [
                                                    Ty.path
                                                      "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                                  ],
                                                [
                                                  Ty.apply
                                                    (Ty.path "&")
                                                    []
                                                    [
                                                      Ty.path
                                                        "move_bytecode_verifier::reference_safety::abstract_state::AbstractValue"
                                                    ]
                                                ],
                                                "eq",
                                                []
                                              |),
                                              [ self_value; joined_value ]
                                            |)))
                                      ]
                                    |)))
                                | _ => M.impossible "wrong number of arguments"
                                end))
                        ]
                      |)
                    |) in
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                LogicalOp.and (|
                                  M.read (| locals_unchanged |),
                                  ltac:(M.monadic
                                    (M.call_closure (|
                                      M.get_associated_function (|
                                        Ty.apply
                                          (Ty.path "move_borrow_graph::graph::BorrowGraph")
                                          []
                                          [
                                            Ty.tuple [];
                                            Ty.path
                                              "move_bytecode_verifier::reference_safety::abstract_state::Label"
                                          ],
                                        "leq",
                                        []
                                      |),
                                      [
                                        M.SubPointer.get_struct_record_field (|
                                          M.read (| self |),
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                          "borrow_graph"
                                        |);
                                        M.SubPointer.get_struct_record_field (|
                                          joined,
                                          "move_bytecode_verifier::reference_safety::abstract_state::AbstractState",
                                          "borrow_graph"
                                        |)
                                      ]
                                    |)))
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Ok"
                              [
                                Value.StructTuple
                                  "move_bytecode_verifier::absint::JoinResult::Unchanged"
                                  []
                              ]
                          |)));
                      fun γ =>
                        ltac:(M.monadic
                          (let~ _ := M.write (| M.read (| self |), M.read (| joined |) |) in
                          M.alloc (|
                            Value.StructTuple
                              "core::result::Result::Ok"
                              [
                                Value.StructTuple
                                  "move_bytecode_verifier::absint::JoinResult::Changed"
                                  []
                              ]
                          |)))
                    ]
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        M.IsTraitInstance
          "move_bytecode_verifier::absint::AbstractDomain"
          Self
          (* Trait polymorphic types *) []
          (* Instance *) [ ("join", InstanceField.Method join) ].
    End Impl_move_bytecode_verifier_absint_AbstractDomain_for_move_bytecode_verifier_reference_safety_abstract_state_AbstractState.
  End abstract_state.
End reference_safety.
