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

Module gas_algebra.
  (*
  Enum InternalGasUnit
  {
    const_params := [];
    ty_params := [];
    variants := [];
  }
  *)
  
  (*
  Enum Byte
  {
    const_params := [];
    ty_params := [];
    variants := [];
  }
  *)
  
  (*
  Enum KibiByte
  {
    const_params := [];
    ty_params := [];
    variants := [];
  }
  *)
  
  (*
  Enum MebiByte
  {
    const_params := [];
    ty_params := [];
    variants := [];
  }
  *)
  
  (*
  Enum GibiByte
  {
    const_params := [];
    ty_params := [];
    variants := [];
  }
  *)
  
  (*
  Enum AbstractMemoryUnit
  {
    const_params := [];
    ty_params := [];
    variants := [];
  }
  *)
  
  (*
  Enum Arg
  {
    const_params := [];
    ty_params := [];
    variants := [];
  }
  *)
  
  (* StructRecord
    {
      name := "UnitDiv";
      const_params := [];
      ty_params := [ "U1"; "U2" ];
      fields :=
        [ ("phantom", Ty.apply (Ty.path "core::marker::PhantomData") [] [ Ty.tuple [ U1; U2 ] ]) ];
    } *)
  
  (* StructRecord
    {
      name := "GasQuantity";
      const_params := [];
      ty_params := [ "U" ];
      fields :=
        [
          ("val", Ty.path "u64");
          ("phantom", Ty.apply (Ty.path "core::marker::PhantomData") [] [ U ])
        ];
    } *)
  
  Module underscore.
    Module Impl_serde_ser_Serialize_for_move_core_types_gas_algebra_GasQuantity_U.
      Definition Self (U : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
      
      (* Serialize *)
      Definition serialize (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self U in
        match ε, τ, α with
        | [], [ __S ], [ self; __serializer ] =>
          ltac:(M.monadic
            (let self := M.alloc (| self |) in
            let __serializer := M.alloc (| __serializer |) in
            M.catch_return (|
              ltac:(M.monadic
                (M.read (|
                  let~ __serde_state :=
                    M.copy (|
                      M.match_operator (|
                        M.alloc (|
                          M.call_closure (|
                            M.get_trait_method (|
                              "serde::ser::Serializer",
                              __S,
                              [],
                              "serialize_struct",
                              []
                            |),
                            [
                              M.read (| __serializer |);
                              M.read (| Value.String "GasQuantity" |);
                              BinOp.Wrap.add (|
                                BinOp.Wrap.add (|
                                  M.rust_cast (Value.Bool false),
                                  Value.Integer IntegerKind.Usize 1
                                |),
                                Value.Integer IntegerKind.Usize 1
                              |)
                            ]
                          |)
                        |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::result::Result::Ok",
                                  0
                                |) in
                              let __val := M.copy (| γ0_0 |) in
                              __val));
                          fun γ =>
                            ltac:(M.monadic
                              (let γ0_0 :=
                                M.SubPointer.get_struct_tuple_field (|
                                  γ,
                                  "core::result::Result::Err",
                                  0
                                |) in
                              let __err := M.copy (| γ0_0 |) in
                              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 (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "serde::ser::SerializeStruct",
                            Ty.associated,
                            [],
                            "serialize_field",
                            [ Ty.path "u64" ]
                          |),
                          [
                            __serde_state;
                            M.read (| Value.String "val" |);
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "move_core_types::gas_algebra::GasQuantity",
                              "val"
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::result::Result::Ok",
                                0
                              |) in
                            let __val := M.copy (| γ0_0 |) in
                            __val));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::result::Result::Err",
                                0
                              |) in
                            let __err := M.copy (| γ0_0 |) in
                            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 (|
                        M.call_closure (|
                          M.get_trait_method (|
                            "serde::ser::SerializeStruct",
                            Ty.associated,
                            [],
                            "serialize_field",
                            [ Ty.apply (Ty.path "core::marker::PhantomData") [] [ U ] ]
                          |),
                          [
                            __serde_state;
                            M.read (| Value.String "phantom" |);
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "move_core_types::gas_algebra::GasQuantity",
                              "phantom"
                            |)
                          ]
                        |)
                      |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::result::Result::Ok",
                                0
                              |) in
                            let __val := M.copy (| γ0_0 |) in
                            __val));
                        fun γ =>
                          ltac:(M.monadic
                            (let γ0_0 :=
                              M.SubPointer.get_struct_tuple_field (|
                                γ,
                                "core::result::Result::Err",
                                0
                              |) in
                            let __err := M.copy (| γ0_0 |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  M.return_ (|
                                    Value.StructTuple
                                      "core::result::Result::Err"
                                      [ M.read (| __err |) ]
                                  |)
                                |)
                              |)
                            |)))
                      ]
                    |) in
                  M.alloc (|
                    M.call_closure (|
                      M.get_trait_method (|
                        "serde::ser::SerializeStruct",
                        Ty.associated,
                        [],
                        "end",
                        []
                      |),
                      [ M.read (| __serde_state |) ]
                    |)
                  |)
                |)))
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (U : Ty.t),
        M.IsTraitInstance
          "serde::ser::Serialize"
          (Self U)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("serialize", InstanceField.Method (serialize U)) ].
    End Impl_serde_ser_Serialize_for_move_core_types_gas_algebra_GasQuantity_U.
    Module Impl_serde_de_Deserialize_for_move_core_types_gas_algebra_GasQuantity_U.
      Definition Self (U : Ty.t) : Ty.t :=
        Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
      
      (* Deserialize *)
      Definition deserialize (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
        let Self : Ty.t := Self U in
        match ε, τ, α with
        | [], [ __D ], [ __deserializer ] =>
          ltac:(M.monadic
            (let __deserializer := M.alloc (| __deserializer |) in
            M.call_closure (|
              M.get_trait_method (|
                "serde::de::Deserializer",
                __D,
                [],
                "deserialize_struct",
                [
                  Ty.apply
                    (Ty.path "move_core_types::gas_algebra::_'1::deserialize::__Visitor")
                    []
                    [ U ]
                ]
              |),
              [
                M.read (| __deserializer |);
                M.read (| Value.String "GasQuantity" |);
                M.read (|
                  M.get_constant (| "move_core_types::gas_algebra::_'1::deserialize::FIELDS" |)
                |);
                Value.StructRecord
                  "move_core_types::gas_algebra::_'1::deserialize::__Visitor"
                  [
                    ("marker", Value.StructTuple "core::marker::PhantomData" []);
                    ("lifetime", Value.StructTuple "core::marker::PhantomData" [])
                  ]
              ]
            |)))
        | _, _, _ => M.impossible "wrong number of arguments"
        end.
      
      Axiom Implements :
        forall (U : Ty.t),
        M.IsTraitInstance
          "serde::de::Deserialize"
          (Self U)
          (* Trait polymorphic types *) []
          (* Instance *) [ ("deserialize", InstanceField.Method (deserialize U)) ].
    End Impl_serde_de_Deserialize_for_move_core_types_gas_algebra_GasQuantity_U.
  End underscore.
  
  
  Axiom InternalGas :
    (Ty.path "move_core_types::gas_algebra::InternalGas") =
      (Ty.apply
        (Ty.path "move_core_types::gas_algebra::GasQuantity")
        []
        [ Ty.path "move_core_types::gas_algebra::InternalGasUnit" ]).
  
  Axiom NumBytes :
    (Ty.path "move_core_types::gas_algebra::NumBytes") =
      (Ty.apply
        (Ty.path "move_core_types::gas_algebra::GasQuantity")
        []
        [ Ty.path "move_core_types::gas_algebra::Byte" ]).
  
  Axiom NumArgs :
    (Ty.path "move_core_types::gas_algebra::NumArgs") =
      (Ty.apply
        (Ty.path "move_core_types::gas_algebra::GasQuantity")
        []
        [ Ty.path "move_core_types::gas_algebra::Arg" ]).
  
  Axiom AbstractMemorySize :
    (Ty.path "move_core_types::gas_algebra::AbstractMemorySize") =
      (Ty.apply
        (Ty.path "move_core_types::gas_algebra::GasQuantity")
        []
        [ Ty.path "move_core_types::gas_algebra::AbstractMemoryUnit" ]).
  
  Axiom InternalGasPerByte :
    (Ty.path "move_core_types::gas_algebra::InternalGasPerByte") =
      (Ty.apply
        (Ty.path "move_core_types::gas_algebra::GasQuantity")
        []
        [
          Ty.apply
            (Ty.path "move_core_types::gas_algebra::UnitDiv")
            []
            [
              Ty.path "move_core_types::gas_algebra::InternalGasUnit";
              Ty.path "move_core_types::gas_algebra::Byte"
            ]
        ]).
  
  Axiom InternalGasPerAbstractMemoryUnit :
    (Ty.path "move_core_types::gas_algebra::InternalGasPerAbstractMemoryUnit") =
      (Ty.apply
        (Ty.path "move_core_types::gas_algebra::GasQuantity")
        []
        [
          Ty.apply
            (Ty.path "move_core_types::gas_algebra::UnitDiv")
            []
            [
              Ty.path "move_core_types::gas_algebra::InternalGasUnit";
              Ty.path "move_core_types::gas_algebra::AbstractMemoryUnit"
            ]
        ]).
  
  Axiom InternalGasPerArg :
    (Ty.path "move_core_types::gas_algebra::InternalGasPerArg") =
      (Ty.apply
        (Ty.path "move_core_types::gas_algebra::GasQuantity")
        []
        [
          Ty.apply
            (Ty.path "move_core_types::gas_algebra::UnitDiv")
            []
            [
              Ty.path "move_core_types::gas_algebra::InternalGasUnit";
              Ty.path "move_core_types::gas_algebra::Arg"
            ]
        ]).
  
  Definition value_BOX_ABSTRACT_SIZE : Value.t :=
    M.run
      ltac:(M.monadic
        (M.alloc (|
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply
                (Ty.path "move_core_types::gas_algebra::GasQuantity")
                []
                [ Ty.path "move_core_types::gas_algebra::AbstractMemoryUnit" ],
              "new",
              []
            |),
            [ Value.Integer IntegerKind.U64 16 ]
          |)
        |))).
  
  Definition value_ENUM_BASE_ABSTRACT_SIZE : Value.t :=
    M.run
      ltac:(M.monadic
        (M.alloc (|
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply
                (Ty.path "move_core_types::gas_algebra::GasQuantity")
                []
                [ Ty.path "move_core_types::gas_algebra::AbstractMemoryUnit" ],
              "new",
              []
            |),
            [ Value.Integer IntegerKind.U64 8 ]
          |)
        |))).
  
  Module Impl_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        pub const fn new(val: u64) -> Self {
            Self {
                val,
                phantom: PhantomData,
            }
        }
    *)
    Definition new (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ val ] =>
        ltac:(M.monadic
          (let val := M.alloc (| val |) in
          Value.StructRecord
            "move_core_types::gas_algebra::GasQuantity"
            [
              ("val", M.read (| val |));
              ("phantom", Value.StructTuple "core::marker::PhantomData" [])
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_new : forall (U : Ty.t), M.IsAssociatedFunction (Self U) "new" (new U).
    
    (*
        pub const fn zero() -> Self {
            Self::new(0)
        }
    *)
    Definition zero (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
              "new",
              []
            |),
            [ Value.Integer IntegerKind.U64 0 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_zero :
      forall (U : Ty.t),
      M.IsAssociatedFunction (Self U) "zero" (zero U).
    
    (*
        pub const fn one() -> Self {
            Self::new(1)
        }
    *)
    Definition one (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [] =>
        ltac:(M.monadic
          (M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
              "new",
              []
            |),
            [ Value.Integer IntegerKind.U64 1 ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_one : forall (U : Ty.t), M.IsAssociatedFunction (Self U) "one" (one U).
    
    (*
        pub const fn is_zero(&self) -> bool {
            self.val == 0
        }
    *)
    Definition is_zero (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          BinOp.eq (|
            M.read (|
              M.SubPointer.get_struct_record_field (|
                M.read (| self |),
                "move_core_types::gas_algebra::GasQuantity",
                "val"
              |)
            |),
            Value.Integer IntegerKind.U64 0
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_is_zero :
      forall (U : Ty.t),
      M.IsAssociatedFunction (Self U) "is_zero" (is_zero U).
    (*
        fn cmp_impl(&self, other: &Self) -> Ordering {
            self.val.cmp(&other.val)
        }
    *)
    Definition cmp_impl (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.call_closure (|
            M.get_trait_method (| "core::cmp::Ord", Ty.path "u64", [], "cmp", [] |),
            [
              M.SubPointer.get_struct_record_field (|
                M.read (| self |),
                "move_core_types::gas_algebra::GasQuantity",
                "val"
              |);
              M.SubPointer.get_struct_record_field (|
                M.read (| other |),
                "move_core_types::gas_algebra::GasQuantity",
                "val"
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_cmp_impl :
      forall (U : Ty.t),
      M.IsAssociatedFunction (Self U) "cmp_impl" (cmp_impl U).
    (*
        pub fn checked_sub(self, other: Self) -> Option<Self> {
            self.val.checked_sub(other.val).map(Self::new)
        }
    *)
    Definition checked_sub (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "core::option::Option") [] [ Ty.path "u64" ],
              "map",
              [
                Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ];
                Ty.function
                  [ Ty.path "u64" ]
                  (Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ])
              ]
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "checked_sub", [] |),
                [
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      self,
                      "move_core_types::gas_algebra::GasQuantity",
                      "val"
                    |)
                  |);
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      other,
                      "move_core_types::gas_algebra::GasQuantity",
                      "val"
                    |)
                  |)
                ]
              |);
              M.get_associated_function (|
                Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
                "new",
                []
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_checked_sub :
      forall (U : Ty.t),
      M.IsAssociatedFunction (Self U) "checked_sub" (checked_sub U).
    
    (*
        pub fn saturating_sub(self, other: Self) -> Self {
            self.val.saturating_sub(other.val).into()
        }
    *)
    Definition saturating_sub
        (U : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.call_closure (|
            M.get_trait_method (|
              "core::convert::Into",
              Ty.path "u64",
              [ Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ] ],
              "into",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "saturating_sub", [] |),
                [
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      self,
                      "move_core_types::gas_algebra::GasQuantity",
                      "val"
                    |)
                  |);
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      other,
                      "move_core_types::gas_algebra::GasQuantity",
                      "val"
                    |)
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_saturating_sub :
      forall (U : Ty.t),
      M.IsAssociatedFunction (Self U) "saturating_sub" (saturating_sub U).
    (*
        pub fn to_unit<T>(self) -> GasQuantity<T>
        where
            U: ToUnit<T>,
        {
            assert_ne!(U::MULTIPLIER, 0);
    
            GasQuantity::new(self.val.saturating_mul(U::MULTIPLIER))
        }
    *)
    Definition to_unit (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.read (|
            let~ _ :=
              M.match_operator (|
                M.alloc (|
                  Value.Tuple
                    [
                      M.get_constant (| "move_core_types::gas_algebra::ToUnit::MULTIPLIER" |);
                      M.alloc (| Value.Integer IntegerKind.U64 0 |)
                    ]
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                      let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                      let left_val := M.copy (| γ0_0 |) in
                      let right_val := M.copy (| γ0_1 |) in
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    BinOp.eq (|
                                      M.read (| M.read (| left_val |) |),
                                      M.read (| M.read (| right_val |) |)
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    let~ kind :=
                                      M.alloc (|
                                        Value.StructTuple "core::panicking::AssertKind::Ne" []
                                      |) in
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_function (|
                                          "core::panicking::assert_failed",
                                          [ Ty.path "u64"; Ty.path "u64" ]
                                        |),
                                        [
                                          M.read (| kind |);
                                          M.read (| left_val |);
                                          M.read (| right_val |);
                                          Value.StructTuple "core::option::Option::None" []
                                        ]
                                      |)
                                    |)
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ T ],
                  "new",
                  []
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Ty.path "u64", "saturating_mul", [] |),
                    [
                      M.read (|
                        M.SubPointer.get_struct_record_field (|
                          self,
                          "move_core_types::gas_algebra::GasQuantity",
                          "val"
                        |)
                      |);
                      M.read (|
                        M.get_constant (| "move_core_types::gas_algebra::ToUnit::MULTIPLIER" |)
                      |)
                    ]
                  |)
                ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_unit :
      forall (U : Ty.t),
      M.IsAssociatedFunction (Self U) "to_unit" (to_unit U).
    
    (*
        pub fn to_unit_round_down<T>(self) -> GasQuantity<T>
        where
            U: ToUnitFractional<T>,
        {
            GasQuantity::new(apply_ratio_round_down(
                self.val,
                U::NOMINATOR,
                U::DENOMINATOR,
            ))
        }
    *)
    Definition to_unit_round_down
        (U : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ T ],
              "new",
              []
            |),
            [
              M.call_closure (|
                M.get_function (| "move_core_types::gas_algebra::apply_ratio_round_down", [] |),
                [
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      self,
                      "move_core_types::gas_algebra::GasQuantity",
                      "val"
                    |)
                  |);
                  M.read (|
                    M.get_constant (| "move_core_types::gas_algebra::ToUnitFractional::NOMINATOR" |)
                  |);
                  M.read (|
                    M.get_constant (|
                      "move_core_types::gas_algebra::ToUnitFractional::DENOMINATOR"
                    |)
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_unit_round_down :
      forall (U : Ty.t),
      M.IsAssociatedFunction (Self U) "to_unit_round_down" (to_unit_round_down U).
    
    (*
        pub fn to_unit_round_up<T>(self) -> GasQuantity<T>
        where
            U: ToUnitFractional<T>,
        {
            GasQuantity::new(apply_ratio_round_up(self.val, U::NOMINATOR, U::DENOMINATOR))
        }
    *)
    Definition to_unit_round_up
        (U : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [ T ], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ T ],
              "new",
              []
            |),
            [
              M.call_closure (|
                M.get_function (| "move_core_types::gas_algebra::apply_ratio_round_up", [] |),
                [
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      self,
                      "move_core_types::gas_algebra::GasQuantity",
                      "val"
                    |)
                  |);
                  M.read (|
                    M.get_constant (| "move_core_types::gas_algebra::ToUnitFractional::NOMINATOR" |)
                  |);
                  M.read (|
                    M.get_constant (|
                      "move_core_types::gas_algebra::ToUnitFractional::DENOMINATOR"
                    |)
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_unit_round_up :
      forall (U : Ty.t),
      M.IsAssociatedFunction (Self U) "to_unit_round_up" (to_unit_round_up U).
    (*
        pub fn to_unit_with_params<T>(
            self,
            params: &<U as ToUnitWithParams<T>>::Params,
        ) -> GasQuantity<T>
        where
            U: ToUnitWithParams<T>,
        {
            let multiplier = <U as ToUnitWithParams<T>>::multiplier(params);
            assert_ne!(multiplier, 0);
            GasQuantity::new(self.val.saturating_mul(multiplier))
        }
    *)
    Definition to_unit_with_params
        (U : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [ T ], [ self; params ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let params := M.alloc (| params |) in
          M.read (|
            let~ multiplier :=
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "move_core_types::gas_algebra::ToUnitWithParams",
                    U,
                    [ T ],
                    "multiplier",
                    []
                  |),
                  [ M.read (| params |) ]
                |)
              |) in
            let~ _ :=
              M.match_operator (|
                M.alloc (|
                  Value.Tuple [ multiplier; M.alloc (| Value.Integer IntegerKind.U64 0 |) ]
                |),
                [
                  fun γ =>
                    ltac:(M.monadic
                      (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                      let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                      let left_val := M.copy (| γ0_0 |) in
                      let right_val := M.copy (| γ0_1 |) in
                      M.match_operator (|
                        M.alloc (| Value.Tuple [] |),
                        [
                          fun γ =>
                            ltac:(M.monadic
                              (let γ :=
                                M.use
                                  (M.alloc (|
                                    BinOp.eq (|
                                      M.read (| M.read (| left_val |) |),
                                      M.read (| M.read (| right_val |) |)
                                    |)
                                  |)) in
                              let _ :=
                                M.is_constant_or_break_match (|
                                  M.read (| γ |),
                                  Value.Bool true
                                |) in
                              M.alloc (|
                                M.never_to_any (|
                                  M.read (|
                                    let~ kind :=
                                      M.alloc (|
                                        Value.StructTuple "core::panicking::AssertKind::Ne" []
                                      |) in
                                    M.alloc (|
                                      M.call_closure (|
                                        M.get_function (|
                                          "core::panicking::assert_failed",
                                          [ Ty.path "u64"; Ty.path "u64" ]
                                        |),
                                        [
                                          M.read (| kind |);
                                          M.read (| left_val |);
                                          M.read (| right_val |);
                                          Value.StructTuple "core::option::Option::None" []
                                        ]
                                      |)
                                    |)
                                  |)
                                |)
                              |)));
                          fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                        ]
                      |)))
                ]
              |) in
            M.alloc (|
              M.call_closure (|
                M.get_associated_function (|
                  Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ T ],
                  "new",
                  []
                |),
                [
                  M.call_closure (|
                    M.get_associated_function (| Ty.path "u64", "saturating_mul", [] |),
                    [
                      M.read (|
                        M.SubPointer.get_struct_record_field (|
                          self,
                          "move_core_types::gas_algebra::GasQuantity",
                          "val"
                        |)
                      |);
                      M.read (| multiplier |)
                    ]
                  |)
                ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_unit_with_params :
      forall (U : Ty.t),
      M.IsAssociatedFunction (Self U) "to_unit_with_params" (to_unit_with_params U).
    
    (*
        pub fn to_unit_round_down_with_params<T>(
            self,
            params: &<U as ToUnitFractionalWithParams<T>>::Params,
        ) -> GasQuantity<T>
        where
            U: ToUnitFractionalWithParams<T>,
        {
            let (n, d) = <U as ToUnitFractionalWithParams<T>>::ratio(params);
            GasQuantity::new(apply_ratio_round_down(self.val, n, d))
        }
    *)
    Definition to_unit_round_down_with_params
        (U : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [ T ], [ self; params ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let params := M.alloc (| params |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "move_core_types::gas_algebra::ToUnitFractionalWithParams",
                    U,
                    [ T ],
                    "ratio",
                    []
                  |),
                  [ M.read (| params |) ]
                |)
              |),
              [
                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 n := M.copy (| γ0_0 |) in
                    let d := M.copy (| γ0_1 |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ T ],
                          "new",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_function (|
                              "move_core_types::gas_algebra::apply_ratio_round_down",
                              []
                            |),
                            [
                              M.read (|
                                M.SubPointer.get_struct_record_field (|
                                  self,
                                  "move_core_types::gas_algebra::GasQuantity",
                                  "val"
                                |)
                              |);
                              M.read (| n |);
                              M.read (| d |)
                            ]
                          |)
                        ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_unit_round_down_with_params :
      forall (U : Ty.t),
      M.IsAssociatedFunction
        (Self U)
        "to_unit_round_down_with_params"
        (to_unit_round_down_with_params U).
    
    (*
        pub fn to_unit_round_up_with_params<T>(
            self,
            params: &<U as ToUnitFractionalWithParams<T>>::Params,
        ) -> GasQuantity<T>
        where
            U: ToUnitFractionalWithParams<T>,
        {
            let (n, d) = <U as ToUnitFractionalWithParams<T>>::ratio(params);
            GasQuantity::new(apply_ratio_round_up(self.val, n, d))
        }
    *)
    Definition to_unit_round_up_with_params
        (U : Ty.t)
        (ε : list Value.t)
        (τ : list Ty.t)
        (α : list Value.t)
        : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [ T ], [ self; params ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let params := M.alloc (| params |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_trait_method (|
                    "move_core_types::gas_algebra::ToUnitFractionalWithParams",
                    U,
                    [ T ],
                    "ratio",
                    []
                  |),
                  [ M.read (| params |) ]
                |)
              |),
              [
                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 n := M.copy (| γ0_0 |) in
                    let d := M.copy (| γ0_1 |) in
                    M.alloc (|
                      M.call_closure (|
                        M.get_associated_function (|
                          Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ T ],
                          "new",
                          []
                        |),
                        [
                          M.call_closure (|
                            M.get_function (|
                              "move_core_types::gas_algebra::apply_ratio_round_up",
                              []
                            |),
                            [
                              M.read (|
                                M.SubPointer.get_struct_record_field (|
                                  self,
                                  "move_core_types::gas_algebra::GasQuantity",
                                  "val"
                                |)
                              |);
                              M.read (| n |);
                              M.read (| d |)
                            ]
                          |)
                        ]
                      |)
                    |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom AssociatedFunction_to_unit_round_up_with_params :
      forall (U : Ty.t),
      M.IsAssociatedFunction
        (Self U)
        "to_unit_round_up_with_params"
        (to_unit_round_up_with_params U).
  End Impl_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_convert_From_u64_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        fn from(val: u64) -> Self {
            Self::new(val)
        }
    *)
    Definition from (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ val ] =>
        ltac:(M.monadic
          (let val := M.alloc (| val |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
              "new",
              []
            |),
            [ M.read (| val |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::convert::From"
        (Self U)
        (* Trait polymorphic types *) [ (* T *) Ty.path "u64" ]
        (* Instance *) [ ("from", InstanceField.Method (from U)) ].
  End Impl_core_convert_From_u64_for_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_convert_From_move_core_types_gas_algebra_GasQuantity_U_for_u64.
    Definition Self (U : Ty.t) : Ty.t := Ty.path "u64".
    
    (*
        fn from(gas: GasQuantity<U>) -> Self {
            gas.val
        }
    *)
    Definition from (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ gas ] =>
        ltac:(M.monadic
          (let gas := M.alloc (| gas |) in
          M.read (|
            M.SubPointer.get_struct_record_field (|
              gas,
              "move_core_types::gas_algebra::GasQuantity",
              "val"
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::convert::From"
        (Self U)
        (* Trait polymorphic types *)
        [ (* T *) Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ] ]
        (* Instance *) [ ("from", InstanceField.Method (from U)) ].
  End Impl_core_convert_From_move_core_types_gas_algebra_GasQuantity_U_for_u64.
  
  Module Impl_core_clone_Clone_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        fn clone(&self) -> Self {
            Self::new(self.val)
        }
    *)
    Definition clone (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
              "new",
              []
            |),
            [
              M.read (|
                M.SubPointer.get_struct_record_field (|
                  M.read (| self |),
                  "move_core_types::gas_algebra::GasQuantity",
                  "val"
                |)
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::clone::Clone"
        (Self U)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("clone", InstanceField.Method (clone U)) ].
  End Impl_core_clone_Clone_for_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_marker_Copy_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::marker::Copy"
        (Self U)
        (* Trait polymorphic types *) []
        (* Instance *) [].
  End Impl_core_marker_Copy_for_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_fmt_Display_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "{}", self.val)
        }
    *)
    Definition fmt (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let f := M.alloc (| f |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "core::fmt::Formatter", "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 "" |) ] |);
                  M.alloc (|
                    Value.Array
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::rt::Argument",
                            "new_display",
                            [ Ty.path "u64" ]
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "move_core_types::gas_algebra::GasQuantity",
                              "val"
                            |)
                          ]
                        |)
                      ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::fmt::Display"
        (Self U)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("fmt", InstanceField.Method (fmt U)) ].
  End Impl_core_fmt_Display_for_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_fmt_Debug_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "{} ({})", self.val, std::any::type_name::<U>())
        }
    *)
    Definition fmt (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; f ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let f := M.alloc (| f |) in
          M.call_closure (|
            M.get_associated_function (| Ty.path "core::fmt::Formatter", "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 "" |);
                        M.read (| Value.String " (" |);
                        M.read (| Value.String ")" |)
                      ]
                  |);
                  M.alloc (|
                    Value.Array
                      [
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::rt::Argument",
                            "new_display",
                            [ Ty.path "u64" ]
                          |),
                          [
                            M.SubPointer.get_struct_record_field (|
                              M.read (| self |),
                              "move_core_types::gas_algebra::GasQuantity",
                              "val"
                            |)
                          ]
                        |);
                        M.call_closure (|
                          M.get_associated_function (|
                            Ty.path "core::fmt::rt::Argument",
                            "new_display",
                            [ Ty.apply (Ty.path "&") [] [ Ty.path "str" ] ]
                          |),
                          [
                            M.alloc (|
                              M.call_closure (|
                                M.get_function (| "core::any::type_name", [ U ] |),
                                []
                              |)
                            |)
                          ]
                        |)
                      ]
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::fmt::Debug"
        (Self U)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("fmt", InstanceField.Method (fmt U)) ].
  End Impl_core_fmt_Debug_for_move_core_types_gas_algebra_GasQuantity_U.
  
  
  Module Impl_core_cmp_PartialEq_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        fn eq(&self, other: &Self) -> bool {
            matches!(self.cmp_impl(other), Ordering::Equal)
        }
    *)
    Definition eq (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.read (|
            M.match_operator (|
              M.alloc (|
                M.call_closure (|
                  M.get_associated_function (|
                    Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
                    "cmp_impl",
                    []
                  |),
                  [ M.read (| self |); M.read (| other |) ]
                |)
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let _ := M.is_struct_tuple (| γ, "core::cmp::Ordering::Equal" |) in
                    M.alloc (| Value.Bool true |)));
                fun γ => ltac:(M.monadic (M.alloc (| Value.Bool false |)))
              ]
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::cmp::PartialEq"
        (Self U)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("eq", InstanceField.Method (eq U)) ].
  End Impl_core_cmp_PartialEq_for_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_cmp_Eq_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance "core::cmp::Eq" (Self U) (* Trait polymorphic types *) [] (* Instance *) [].
  End Impl_core_cmp_Eq_for_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_cmp_PartialOrd_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
            Some(std::cmp::Ord::cmp(self, other))
        }
    *)
    Definition partial_cmp (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          Value.StructTuple
            "core::option::Option::Some"
            [
              M.call_closure (|
                M.get_trait_method (|
                  "core::cmp::Ord",
                  Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
                  [],
                  "cmp",
                  []
                |),
                [ M.read (| self |); M.read (| other |) ]
              |)
            ]))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::cmp::PartialOrd"
        (Self U)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("partial_cmp", InstanceField.Method (partial_cmp U)) ].
  End Impl_core_cmp_PartialOrd_for_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_cmp_Ord_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        fn cmp(&self, other: &Self) -> Ordering {
            self.cmp_impl(other)
        }
    *)
    Definition cmp (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; other ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let other := M.alloc (| other |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
              "cmp_impl",
              []
            |),
            [ M.read (| self |); M.read (| other |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::cmp::Ord"
        (Self U)
        (* Trait polymorphic types *) []
        (* Instance *) [ ("cmp", InstanceField.Method (cmp U)) ].
  End Impl_core_cmp_Ord_for_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_ops_arith_Add_move_core_types_gas_algebra_GasQuantity_U_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*     type Output = Self; *)
    Definition _Output (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        fn add(self, rhs: Self) -> Self::Output {
            Self::new(self.val.saturating_add(rhs.val))
        }
    *)
    Definition add (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_associated_function (|
              Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
              "new",
              []
            |),
            [
              M.call_closure (|
                M.get_associated_function (| Ty.path "u64", "saturating_add", [] |),
                [
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      self,
                      "move_core_types::gas_algebra::GasQuantity",
                      "val"
                    |)
                  |);
                  M.read (|
                    M.SubPointer.get_struct_record_field (|
                      rhs,
                      "move_core_types::gas_algebra::GasQuantity",
                      "val"
                    |)
                  |)
                ]
              |)
            ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::ops::arith::Add"
        (Self U)
        (* Trait polymorphic types *)
        [ (* Rhs *) Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ] ]
        (* Instance *)
        [ ("Output", InstanceField.Ty (_Output U)); ("add", InstanceField.Method (add U)) ].
  End Impl_core_ops_arith_Add_move_core_types_gas_algebra_GasQuantity_U_for_move_core_types_gas_algebra_GasQuantity_U.
  
  Module Impl_core_ops_arith_AddAssign_move_core_types_gas_algebra_GasQuantity_U_for_move_core_types_gas_algebra_GasQuantity_U.
    Definition Self (U : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ].
    
    (*
        fn add_assign(&mut self, rhs: GasQuantity<U>) {
            *self = *self + rhs
        }
    *)
    Definition add_assign (U : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U in
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.read (|
            M.write (|
              M.read (| self |),
              M.call_closure (|
                M.get_trait_method (|
                  "core::ops::arith::Add",
                  Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ],
                  [ Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ] ],
                  "add",
                  []
                |),
                [ M.read (| M.read (| self |) |); M.read (| rhs |) ]
              |)
            |)
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U : Ty.t),
      M.IsTraitInstance
        "core::ops::arith::AddAssign"
        (Self U)
        (* Trait polymorphic types *)
        [ (* Rhs *) Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U ] ]
        (* Instance *) [ ("add_assign", InstanceField.Method (add_assign U)) ].
  End Impl_core_ops_arith_AddAssign_move_core_types_gas_algebra_GasQuantity_U_for_move_core_types_gas_algebra_GasQuantity_U.
  
  
  (*
  fn mul_impl<U1, U2>(x: GasQuantity<U2>, y: GasQuantity<UnitDiv<U1, U2>>) -> GasQuantity<U1> {
      GasQuantity::new(x.val.saturating_mul(y.val))
  }
  *)
  Definition mul_impl (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [ U1; U2 ], [ x; y ] =>
      ltac:(M.monadic
        (let x := M.alloc (| x |) in
        let y := M.alloc (| y |) in
        M.call_closure (|
          M.get_associated_function (|
            Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U1 ],
            "new",
            []
          |),
          [
            M.call_closure (|
              M.get_associated_function (| Ty.path "u64", "saturating_mul", [] |),
              [
                M.read (|
                  M.SubPointer.get_struct_record_field (|
                    x,
                    "move_core_types::gas_algebra::GasQuantity",
                    "val"
                  |)
                |);
                M.read (|
                  M.SubPointer.get_struct_record_field (|
                    y,
                    "move_core_types::gas_algebra::GasQuantity",
                    "val"
                  |)
                |)
              ]
            |)
          ]
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_mul_impl : M.IsFunction "move_core_types::gas_algebra::mul_impl" mul_impl.
  
  Module Impl_core_ops_arith_Mul_move_core_types_gas_algebra_GasQuantity_move_core_types_gas_algebra_UnitDiv_U1_U2_for_move_core_types_gas_algebra_GasQuantity_U2.
    Definition Self (U1 U2 : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U2 ].
    
    (*     type Output = GasQuantity<U1>; *)
    Definition _Output (U1 U2 : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U1 ].
    
    (*
        fn mul(self, rhs: GasQuantity<UnitDiv<U1, U2>>) -> Self::Output {
            mul_impl(self, rhs)
        }
    *)
    Definition mul (U1 U2 : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U1 U2 in
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "move_core_types::gas_algebra::mul_impl", [ U1; U2 ] |),
            [ M.read (| self |); M.read (| rhs |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U1 U2 : Ty.t),
      M.IsTraitInstance
        "core::ops::arith::Mul"
        (Self U1 U2)
        (* Trait polymorphic types *)
        [
          (* Rhs *)
          Ty.apply
            (Ty.path "move_core_types::gas_algebra::GasQuantity")
            []
            [ Ty.apply (Ty.path "move_core_types::gas_algebra::UnitDiv") [] [ U1; U2 ] ]
        ]
        (* Instance *)
        [ ("Output", InstanceField.Ty (_Output U1 U2)); ("mul", InstanceField.Method (mul U1 U2)) ].
  End Impl_core_ops_arith_Mul_move_core_types_gas_algebra_GasQuantity_move_core_types_gas_algebra_UnitDiv_U1_U2_for_move_core_types_gas_algebra_GasQuantity_U2.
  
  Module Impl_core_ops_arith_Mul_move_core_types_gas_algebra_GasQuantity_U2_for_move_core_types_gas_algebra_GasQuantity_move_core_types_gas_algebra_UnitDiv_U1_U2.
    Definition Self (U1 U2 : Ty.t) : Ty.t :=
      Ty.apply
        (Ty.path "move_core_types::gas_algebra::GasQuantity")
        []
        [ Ty.apply (Ty.path "move_core_types::gas_algebra::UnitDiv") [] [ U1; U2 ] ].
    
    (*     type Output = GasQuantity<U1>; *)
    Definition _Output (U1 U2 : Ty.t) : Ty.t :=
      Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U1 ].
    
    (*
        fn mul(self, rhs: GasQuantity<U2>) -> Self::Output {
            mul_impl(rhs, self)
        }
    *)
    Definition mul (U1 U2 : Ty.t) (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
      let Self : Ty.t := Self U1 U2 in
      match ε, τ, α with
      | [], [], [ self; rhs ] =>
        ltac:(M.monadic
          (let self := M.alloc (| self |) in
          let rhs := M.alloc (| rhs |) in
          M.call_closure (|
            M.get_function (| "move_core_types::gas_algebra::mul_impl", [ U1; U2 ] |),
            [ M.read (| rhs |); M.read (| self |) ]
          |)))
      | _, _, _ => M.impossible "wrong number of arguments"
      end.
    
    Axiom Implements :
      forall (U1 U2 : Ty.t),
      M.IsTraitInstance
        "core::ops::arith::Mul"
        (Self U1 U2)
        (* Trait polymorphic types *)
        [ (* Rhs *) Ty.apply (Ty.path "move_core_types::gas_algebra::GasQuantity") [] [ U2 ] ]
        (* Instance *)
        [ ("Output", InstanceField.Ty (_Output U1 U2)); ("mul", InstanceField.Method (mul U1 U2)) ].
  End Impl_core_ops_arith_Mul_move_core_types_gas_algebra_GasQuantity_U2_for_move_core_types_gas_algebra_GasQuantity_move_core_types_gas_algebra_UnitDiv_U1_U2.
  
  (*
  fn apply_ratio_round_down(val: u64, nominator: u64, denominator: u64) -> u64 {
      assert_ne!(nominator, 0);
      assert_ne!(denominator, 0);
  
      let res = val as u128 * nominator as u128 / denominator as u128;
      if res > u64::MAX as u128 {
          u64::MAX
      } else {
          res as u64
      }
  }
  *)
  Definition apply_ratio_round_down (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ val; nominator; denominator ] =>
      ltac:(M.monadic
        (let val := M.alloc (| val |) in
        let nominator := M.alloc (| nominator |) in
        let denominator := M.alloc (| denominator |) in
        M.read (|
          let~ _ :=
            M.match_operator (|
              M.alloc (|
                Value.Tuple [ nominator; M.alloc (| Value.Integer IntegerKind.U64 0 |) ]
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                    let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                    let left_val := M.copy (| γ0_0 |) in
                    let right_val := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| M.read (| left_val |) |),
                                    M.read (| M.read (| right_val |) |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  let~ kind :=
                                    M.alloc (|
                                      Value.StructTuple "core::panicking::AssertKind::Ne" []
                                    |) in
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::panicking::assert_failed",
                                        [ Ty.path "u64"; Ty.path "u64" ]
                                      |),
                                      [
                                        M.read (| kind |);
                                        M.read (| left_val |);
                                        M.read (| right_val |);
                                        Value.StructTuple "core::option::Option::None" []
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |)))
              ]
            |) in
          let~ _ :=
            M.match_operator (|
              M.alloc (|
                Value.Tuple [ denominator; M.alloc (| Value.Integer IntegerKind.U64 0 |) ]
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                    let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                    let left_val := M.copy (| γ0_0 |) in
                    let right_val := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| M.read (| left_val |) |),
                                    M.read (| M.read (| right_val |) |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  let~ kind :=
                                    M.alloc (|
                                      Value.StructTuple "core::panicking::AssertKind::Ne" []
                                    |) in
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::panicking::assert_failed",
                                        [ Ty.path "u64"; Ty.path "u64" ]
                                      |),
                                      [
                                        M.read (| kind |);
                                        M.read (| left_val |);
                                        M.read (| right_val |);
                                        Value.StructTuple "core::option::Option::None" []
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |)))
              ]
            |) in
          let~ res :=
            M.alloc (|
              BinOp.Wrap.div (|
                BinOp.Wrap.mul (|
                  M.rust_cast (M.read (| val |)),
                  M.rust_cast (M.read (| nominator |))
                |),
                M.rust_cast (M.read (| denominator |))
              |)
            |) in
          M.match_operator (|
            M.alloc (| Value.Tuple [] |),
            [
              fun γ =>
                ltac:(M.monadic
                  (let γ :=
                    M.use
                      (M.alloc (|
                        BinOp.gt (|
                          M.read (| res |),
                          M.rust_cast (M.read (| M.get_constant (| "core::num::MAX" |) |))
                        |)
                      |)) in
                  let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                  M.get_constant (| "core::num::MAX" |)));
              fun γ => ltac:(M.monadic (M.alloc (| M.rust_cast (M.read (| res |)) |)))
            ]
          |)
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_apply_ratio_round_down :
    M.IsFunction "move_core_types::gas_algebra::apply_ratio_round_down" apply_ratio_round_down.
  
  (*
  fn apply_ratio_round_up(val: u64, nominator: u64, denominator: u64) -> u64 {
      assert_ne!(nominator, 0);
      assert_ne!(denominator, 0);
  
      let n = val as u128 * nominator as u128;
      let d = denominator as u128;
  
      let res = n / d + if n % d == 0 { 0 } else { 1 };
      if res > u64::MAX as u128 {
          u64::MAX
      } else {
          res as u64
      }
  }
  *)
  Definition apply_ratio_round_up (ε : list Value.t) (τ : list Ty.t) (α : list Value.t) : M :=
    match ε, τ, α with
    | [], [], [ val; nominator; denominator ] =>
      ltac:(M.monadic
        (let val := M.alloc (| val |) in
        let nominator := M.alloc (| nominator |) in
        let denominator := M.alloc (| denominator |) in
        M.read (|
          let~ _ :=
            M.match_operator (|
              M.alloc (|
                Value.Tuple [ nominator; M.alloc (| Value.Integer IntegerKind.U64 0 |) ]
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                    let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                    let left_val := M.copy (| γ0_0 |) in
                    let right_val := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| M.read (| left_val |) |),
                                    M.read (| M.read (| right_val |) |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  let~ kind :=
                                    M.alloc (|
                                      Value.StructTuple "core::panicking::AssertKind::Ne" []
                                    |) in
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::panicking::assert_failed",
                                        [ Ty.path "u64"; Ty.path "u64" ]
                                      |),
                                      [
                                        M.read (| kind |);
                                        M.read (| left_val |);
                                        M.read (| right_val |);
                                        Value.StructTuple "core::option::Option::None" []
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |)))
              ]
            |) in
          let~ _ :=
            M.match_operator (|
              M.alloc (|
                Value.Tuple [ denominator; M.alloc (| Value.Integer IntegerKind.U64 0 |) ]
              |),
              [
                fun γ =>
                  ltac:(M.monadic
                    (let γ0_0 := M.SubPointer.get_tuple_field (| γ, 0 |) in
                    let γ0_1 := M.SubPointer.get_tuple_field (| γ, 1 |) in
                    let left_val := M.copy (| γ0_0 |) in
                    let right_val := M.copy (| γ0_1 |) in
                    M.match_operator (|
                      M.alloc (| Value.Tuple [] |),
                      [
                        fun γ =>
                          ltac:(M.monadic
                            (let γ :=
                              M.use
                                (M.alloc (|
                                  BinOp.eq (|
                                    M.read (| M.read (| left_val |) |),
                                    M.read (| M.read (| right_val |) |)
                                  |)
                                |)) in
                            let _ :=
                              M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                            M.alloc (|
                              M.never_to_any (|
                                M.read (|
                                  let~ kind :=
                                    M.alloc (|
                                      Value.StructTuple "core::panicking::AssertKind::Ne" []
                                    |) in
                                  M.alloc (|
                                    M.call_closure (|
                                      M.get_function (|
                                        "core::panicking::assert_failed",
                                        [ Ty.path "u64"; Ty.path "u64" ]
                                      |),
                                      [
                                        M.read (| kind |);
                                        M.read (| left_val |);
                                        M.read (| right_val |);
                                        Value.StructTuple "core::option::Option::None" []
                                      ]
                                    |)
                                  |)
                                |)
                              |)
                            |)));
                        fun γ => ltac:(M.monadic (M.alloc (| Value.Tuple [] |)))
                      ]
                    |)))
              ]
            |) in
          let~ n :=
            M.alloc (|
              BinOp.Wrap.mul (|
                M.rust_cast (M.read (| val |)),
                M.rust_cast (M.read (| nominator |))
              |)
            |) in
          let~ d := M.alloc (| M.rust_cast (M.read (| denominator |)) |) in
          let~ res :=
            M.alloc (|
              BinOp.Wrap.add (|
                BinOp.Wrap.div (| M.read (| n |), M.read (| d |) |),
                M.read (|
                  M.match_operator (|
                    M.alloc (| Value.Tuple [] |),
                    [
                      fun γ =>
                        ltac:(M.monadic
                          (let γ :=
                            M.use
                              (M.alloc (|
                                BinOp.eq (|
                                  BinOp.Wrap.rem (| M.read (| n |), M.read (| d |) |),
                                  Value.Integer IntegerKind.U128 0
                                |)
                              |)) in
                          let _ :=
                            M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                          M.alloc (| Value.Integer IntegerKind.U128 0 |)));
                      fun γ => ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U128 1 |)))
                    ]
                  |)
                |)
              |)
            |) in
          M.match_operator (|
            M.alloc (| Value.Tuple [] |),
            [
              fun γ =>
                ltac:(M.monadic
                  (let γ :=
                    M.use
                      (M.alloc (|
                        BinOp.gt (|
                          M.read (| res |),
                          M.rust_cast (M.read (| M.get_constant (| "core::num::MAX" |) |))
                        |)
                      |)) in
                  let _ := M.is_constant_or_break_match (| M.read (| γ |), Value.Bool true |) in
                  M.get_constant (| "core::num::MAX" |)));
              fun γ => ltac:(M.monadic (M.alloc (| M.rust_cast (M.read (| res |)) |)))
            ]
          |)
        |)))
    | _, _, _ => M.impossible "wrong number of arguments"
    end.
  
  Axiom Function_apply_ratio_round_up :
    M.IsFunction "move_core_types::gas_algebra::apply_ratio_round_up" apply_ratio_round_up.
  
  (* Trait *)
  (* Empty module 'ToUnit' *)
  
  (* Trait *)
  (* Empty module 'ToUnitFractional' *)
  
  
  Module Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_Byte_for_move_core_types_gas_algebra_KibiByte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::KibiByte".
    
    (*     const MULTIPLIER: u64 = 1024; *)
    (* Ty.path "u64" *)
    Definition value_MULTIPLIER : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1024 |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnit"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::Byte" ]
        (* Instance *) [ ("value_MULTIPLIER", InstanceField.Constant value_MULTIPLIER) ].
  End Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_Byte_for_move_core_types_gas_algebra_KibiByte.
  
  Module Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_Byte_for_move_core_types_gas_algebra_MebiByte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::MebiByte".
    
    (*     const MULTIPLIER: u64 = 1024 * 1024; *)
    (* Ty.path "u64" *)
    Definition value_MULTIPLIER : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            BinOp.Wrap.mul (|
              Value.Integer IntegerKind.U64 1024,
              Value.Integer IntegerKind.U64 1024
            |)
          |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnit"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::Byte" ]
        (* Instance *) [ ("value_MULTIPLIER", InstanceField.Constant value_MULTIPLIER) ].
  End Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_Byte_for_move_core_types_gas_algebra_MebiByte.
  
  Module Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_Byte_for_move_core_types_gas_algebra_GibiByte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::GibiByte".
    
    (*     const MULTIPLIER: u64 = 1024 * 1024 * 1024; *)
    (* Ty.path "u64" *)
    Definition value_MULTIPLIER : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            BinOp.Wrap.mul (|
              BinOp.Wrap.mul (|
                Value.Integer IntegerKind.U64 1024,
                Value.Integer IntegerKind.U64 1024
              |),
              Value.Integer IntegerKind.U64 1024
            |)
          |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnit"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::Byte" ]
        (* Instance *) [ ("value_MULTIPLIER", InstanceField.Constant value_MULTIPLIER) ].
  End Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_Byte_for_move_core_types_gas_algebra_GibiByte.
  
  Module Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_KibiByte_for_move_core_types_gas_algebra_MebiByte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::MebiByte".
    
    (*     const MULTIPLIER: u64 = 1024; *)
    (* Ty.path "u64" *)
    Definition value_MULTIPLIER : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1024 |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnit"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::KibiByte" ]
        (* Instance *) [ ("value_MULTIPLIER", InstanceField.Constant value_MULTIPLIER) ].
  End Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_KibiByte_for_move_core_types_gas_algebra_MebiByte.
  
  Module Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_KibiByte_for_move_core_types_gas_algebra_GibiByte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::GibiByte".
    
    (*     const MULTIPLIER: u64 = 1024 * 1024; *)
    (* Ty.path "u64" *)
    Definition value_MULTIPLIER : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            BinOp.Wrap.mul (|
              Value.Integer IntegerKind.U64 1024,
              Value.Integer IntegerKind.U64 1024
            |)
          |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnit"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::KibiByte" ]
        (* Instance *) [ ("value_MULTIPLIER", InstanceField.Constant value_MULTIPLIER) ].
  End Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_KibiByte_for_move_core_types_gas_algebra_GibiByte.
  
  Module Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_MebiByte_for_move_core_types_gas_algebra_GibiByte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::GibiByte".
    
    (*     const MULTIPLIER: u64 = 1024; *)
    (* Ty.path "u64" *)
    Definition value_MULTIPLIER : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1024 |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnit"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::MebiByte" ]
        (* Instance *) [ ("value_MULTIPLIER", InstanceField.Constant value_MULTIPLIER) ].
  End Impl_move_core_types_gas_algebra_ToUnit_move_core_types_gas_algebra_MebiByte_for_move_core_types_gas_algebra_GibiByte.
  
  Module Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_KibiByte_for_move_core_types_gas_algebra_Byte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::Byte".
    
    (*     const NOMINATOR: u64 = 1; *)
    (* Ty.path "u64" *)
    Definition value_NOMINATOR : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1 |))).
    
    (*     const DENOMINATOR: u64 = 1024; *)
    (* Ty.path "u64" *)
    Definition value_DENOMINATOR : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1024 |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnitFractional"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::KibiByte" ]
        (* Instance *)
        [
          ("value_NOMINATOR", InstanceField.Constant value_NOMINATOR);
          ("value_DENOMINATOR", InstanceField.Constant value_DENOMINATOR)
        ].
  End Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_KibiByte_for_move_core_types_gas_algebra_Byte.
  
  Module Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_MebiByte_for_move_core_types_gas_algebra_KibiByte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::KibiByte".
    
    (*     const NOMINATOR: u64 = 1; *)
    (* Ty.path "u64" *)
    Definition value_NOMINATOR : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1 |))).
    
    (*     const DENOMINATOR: u64 = 1024; *)
    (* Ty.path "u64" *)
    Definition value_DENOMINATOR : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1024 |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnitFractional"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::MebiByte" ]
        (* Instance *)
        [
          ("value_NOMINATOR", InstanceField.Constant value_NOMINATOR);
          ("value_DENOMINATOR", InstanceField.Constant value_DENOMINATOR)
        ].
  End Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_MebiByte_for_move_core_types_gas_algebra_KibiByte.
  
  Module Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_MebiByte_for_move_core_types_gas_algebra_Byte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::Byte".
    
    (*     const NOMINATOR: u64 = 1; *)
    (* Ty.path "u64" *)
    Definition value_NOMINATOR : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1 |))).
    
    (*     const DENOMINATOR: u64 = 1024 * 1024; *)
    (* Ty.path "u64" *)
    Definition value_DENOMINATOR : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            BinOp.Wrap.mul (|
              Value.Integer IntegerKind.U64 1024,
              Value.Integer IntegerKind.U64 1024
            |)
          |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnitFractional"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::MebiByte" ]
        (* Instance *)
        [
          ("value_NOMINATOR", InstanceField.Constant value_NOMINATOR);
          ("value_DENOMINATOR", InstanceField.Constant value_DENOMINATOR)
        ].
  End Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_MebiByte_for_move_core_types_gas_algebra_Byte.
  
  Module Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_GibiByte_for_move_core_types_gas_algebra_MebiByte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::MebiByte".
    
    (*     const NOMINATOR: u64 = 1; *)
    (* Ty.path "u64" *)
    Definition value_NOMINATOR : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1 |))).
    
    (*     const DENOMINATOR: u64 = 1024; *)
    (* Ty.path "u64" *)
    Definition value_DENOMINATOR : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1024 |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnitFractional"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::GibiByte" ]
        (* Instance *)
        [
          ("value_NOMINATOR", InstanceField.Constant value_NOMINATOR);
          ("value_DENOMINATOR", InstanceField.Constant value_DENOMINATOR)
        ].
  End Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_GibiByte_for_move_core_types_gas_algebra_MebiByte.
  
  Module Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_GibiByte_for_move_core_types_gas_algebra_KibiByte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::KibiByte".
    
    (*     const NOMINATOR: u64 = 1; *)
    (* Ty.path "u64" *)
    Definition value_NOMINATOR : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1 |))).
    
    (*     const DENOMINATOR: u64 = 1024 * 1024; *)
    (* Ty.path "u64" *)
    Definition value_DENOMINATOR : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            BinOp.Wrap.mul (|
              Value.Integer IntegerKind.U64 1024,
              Value.Integer IntegerKind.U64 1024
            |)
          |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnitFractional"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::GibiByte" ]
        (* Instance *)
        [
          ("value_NOMINATOR", InstanceField.Constant value_NOMINATOR);
          ("value_DENOMINATOR", InstanceField.Constant value_DENOMINATOR)
        ].
  End Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_GibiByte_for_move_core_types_gas_algebra_KibiByte.
  
  Module Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_GibiByte_for_move_core_types_gas_algebra_Byte.
    Definition Self : Ty.t := Ty.path "move_core_types::gas_algebra::Byte".
    
    (*     const NOMINATOR: u64 = 1; *)
    (* Ty.path "u64" *)
    Definition value_NOMINATOR : Value.t :=
      M.run ltac:(M.monadic (M.alloc (| Value.Integer IntegerKind.U64 1 |))).
    
    (*     const DENOMINATOR: u64 = 1024 * 1024 * 1024; *)
    (* Ty.path "u64" *)
    Definition value_DENOMINATOR : Value.t :=
      M.run
        ltac:(M.monadic
          (M.alloc (|
            BinOp.Wrap.mul (|
              BinOp.Wrap.mul (|
                Value.Integer IntegerKind.U64 1024,
                Value.Integer IntegerKind.U64 1024
              |),
              Value.Integer IntegerKind.U64 1024
            |)
          |))).
    
    Axiom Implements :
      M.IsTraitInstance
        "move_core_types::gas_algebra::ToUnitFractional"
        Self
        (* Trait polymorphic types *) [ (* U *) Ty.path "move_core_types::gas_algebra::GibiByte" ]
        (* Instance *)
        [
          ("value_NOMINATOR", InstanceField.Constant value_NOMINATOR);
          ("value_DENOMINATOR", InstanceField.Constant value_DENOMINATOR)
        ].
  End Impl_move_core_types_gas_algebra_ToUnitFractional_move_core_types_gas_algebra_GibiByte_for_move_core_types_gas_algebra_Byte.
  
  (* Trait *)
  (* Empty module 'ToUnitWithParams' *)
  
  (* Trait *)
  (* Empty module 'ToUnitFractionalWithParams' *)
  
End gas_algebra.
