Skip to main content

🍬 Script_typed_ir.v

Proofs

See code, Gitlab , OCaml

Recursive predicate specifying that a [ty] from [ty] is comparable.
    Fixpoint t (ty : Script_typed_ir.ty) :=
      match ty with
      | Script_typed_ir.Unit_t
      | Script_typed_ir.Never_t
      | Script_typed_ir.Int_t
      | Script_typed_ir.Nat_t
      | Script_typed_ir.Signature_t
      | Script_typed_ir.String_t
      | Script_typed_ir.Bytes_t
      | Script_typed_ir.Mutez_t
      | Script_typed_ir.Bool_t
      | Script_typed_ir.Key_hash_t
      | Script_typed_ir.Key_t
      | Script_typed_ir.Timestamp_t
      | Script_typed_ir.Chain_id_t
      | Script_typed_ir.Address_t
      | Script_typed_ir.Tx_rollup_l2_address_tTrue
      | Script_typed_ir.Pair_t ty1 ty2 meta Dependent_bool.YesYes
      | Script_typed_ir.Union_t ty1 ty2 meta Dependent_bool.YesYes
        t ty1 t ty2
      | Script_typed_ir.Option_t ty meta Dependent_bool.Yest ty
      | _False
      end.
  End Comparable.

  Module Valid.
Validity predicate for the type [Script_typed_ir.ty]
    Fixpoint t (ty : Script_typed_ir.ty) : Prop :=
      match ty with
      | Script_typed_ir.Unit_t
      | Script_typed_ir.Int_t
      | Script_typed_ir.Nat_t
      | Script_typed_ir.Signature_t
      | Script_typed_ir.String_t
      | Script_typed_ir.Bytes_t
      | Script_typed_ir.Mutez_t
      | Script_typed_ir.Key_hash_t
      | Script_typed_ir.Key_t
      | Script_typed_ir.Timestamp_t
      | Script_typed_ir.Address_t
      | Script_typed_ir.Tx_rollup_l2_address_t
      | Script_typed_ir.Bool_tTrue
      | Script_typed_ir.Pair_t ty1 ty2 metadata dep_bool
      | Script_typed_ir.Union_t ty1 ty2 metadata dep_bool
          ( let sz := (1 +i Script_typed_ir.ty_size ty1 +i
            Script_typed_ir.ty_size ty2) in
            metadata = {| Script_typed_ir.ty_metadata.size := sz |}
            sz Alpha_context.Constants.michelson_maximum_type_size )
          ( let d1 := Script_typed_ir.is_comparable ty1 in
            let d2 := Script_typed_ir.is_comparable ty2 in
            let '(Dependent_bool.Ex_dand dnd) :=
            Dependent_bool.dand_value d1 d2 in dnd = dep_bool )
            t ty1 t ty2
      | Script_typed_ir.Lambda_t ty1 ty2 metadata
          ( let sz := (1 +i Script_typed_ir.ty_size ty1 +i
            Script_typed_ir.ty_size ty2) in
            metadata = {| Script_typed_ir.ty_metadata.size := sz |}
            sz Alpha_context.Constants.michelson_maximum_type_size )
          t ty1 t ty2
      | Script_typed_ir.Option_t ty metadata dep_bool
          ( let sz := (1 +i Script_typed_ir.ty_size ty) in
            metadata = {| Script_typed_ir.ty_metadata.size := sz |}
            sz Alpha_context.Constants.michelson_maximum_type_size )
          t ty
      | Script_typed_ir.List_t ty metadata
          ( let sz := (1 +i Script_typed_ir.ty_size ty) in
            metadata = {| Script_typed_ir.ty_metadata.size := sz |}
            sz Alpha_context.Constants.michelson_maximum_type_size )
          t ty
      | Script_typed_ir.Set_t comp_ty metadata
          ( let sz := (1 +i Script_typed_ir.ty_size comp_ty) in
            metadata = {| Script_typed_ir.ty_metadata.size := sz |}
            sz Alpha_context.Constants.michelson_maximum_type_size )
           t comp_ty Comparable.t comp_ty
      | Script_typed_ir.Map_t comp_ty ty metadata
      | Script_typed_ir.Big_map_t comp_ty ty metadata
          ( let sz := (1 +i Script_typed_ir.ty_size comp_ty +i
            Script_typed_ir.ty_size ty) in
            metadata = {| Script_typed_ir.ty_metadata.size := sz |}
            sz Alpha_context.Constants.michelson_maximum_type_size )
          Comparable.t comp_ty t comp_ty t ty
      | Script_typed_ir.Contract_t ty metadatat ty
          ( let sz := (1 +i Script_typed_ir.ty_size ty) in
            metadata = {| Script_typed_ir.ty_metadata.size := sz |}
            sz Alpha_context.Constants.michelson_maximum_type_size )
            t ty
      | Script_typed_ir.Sapling_transaction_t memo
      | Script_typed_ir.Sapling_transaction_deprecated_t memo
      | Script_typed_ir.Sapling_state_t memo
          Sapling_repr.Memo_size.Valid.t memo
      | Script_typed_ir.Operation_t
      | Script_typed_ir.Chain_id_t
      | Script_typed_ir.Never_t
      | Script_typed_ir.Bls12_381_g1_t
      | Script_typed_ir.Bls12_381_g2_t
      | Script_typed_ir.Bls12_381_fr_tTrue
      | Script_typed_ir.Ticket_t comp_ty metadata
        ( let sz := (1 +i Script_typed_ir.ty_size comp_ty) in
           metadata = {| Script_typed_ir.ty_metadata.size := sz |}
           sz Alpha_context.Constants.michelson_maximum_type_size )
        Comparable.t comp_ty t comp_ty
      | Script_typed_ir.Chest_key_t
      | Script_typed_ir.Chest_tTrue
      end.

IMPORTANT: [proj_rel] below should be replaced everywhere with the underlying function it defines, which is [to_Ty_t] below. Defining the validity of the type [ty] of Michelson types' ASTs. More precisely, [proj_rel ty0 ty] when the AST of [ty0 : Ty.t] is a collapse of the AST of [ty]. @TODO specify when/why it's needed (probably unnecessary) @TODO should probably be renamed or removed
    Inductive proj_rel : Ty.t Script_typed_ir.ty Prop :=
    | Unit_t : proj_rel Ty.Unit Script_typed_ir.Unit_t
    | Int_t : proj_rel (Ty.Num Ty.Num.Int) Script_typed_ir.Int_t
    | Nat_t : proj_rel (Ty.Num Ty.Num.Nat) Script_typed_ir.Nat_t
    | Signature_t : proj_rel Ty.Signature Script_typed_ir.Signature_t
    | String_t : proj_rel Ty.String Script_typed_ir.String_t
    | Bytes_t : proj_rel Ty.Bytes Script_typed_ir.Bytes_t
    | Mutez_t : proj_rel Ty.Mutez Script_typed_ir.Mutez_t
    | Key_hash_t : proj_rel Ty.Key_hash Script_typed_ir.Key_hash_t
    | Key_t : proj_rel Ty.Key Script_typed_ir.Key_t
    | Timestamp_t : proj_rel Ty.Timestamp Script_typed_ir.Timestamp_t
    | Address_t : proj_rel Ty.Address Script_typed_ir.Address_t
    | Tx_rollup_l2_address_t :
      proj_rel Ty.Tx_rollup_l2_address Script_typed_ir.Tx_rollup_l2_address_t
    | Bool_t : proj_rel Ty.Bool Script_typed_ir.Bool_t
    | Pair_t {ty1 ty2 sty1 sty2 meta cmp} :
      proj_rel ty1 sty1
      proj_rel ty2 sty2
      proj_rel (Ty.Pair ty1 ty2) (Script_typed_ir.Pair_t sty1 sty2 meta cmp)
    | Union_t {ty1 ty2 sty1 sty2 meta cmp} :
      proj_rel ty1 sty1
      proj_rel ty2 sty2
      proj_rel (Ty.Union ty1 ty2) (Script_typed_ir.Union_t sty1 sty2 meta cmp)
    | Lambda_t {ty1 ty2 sty1 sty2 meta} :
      proj_rel (Ty.Lambda ty1 ty2) (Script_typed_ir.Lambda_t sty1 sty2 meta)
    | Option_t {ty sty meta cmp} :
      proj_rel ty sty
      proj_rel (Ty.Option ty) (Script_typed_ir.Option_t sty meta cmp)
    | List_t {ty sty meta} :
      proj_rel ty sty
      proj_rel (Ty.List ty) (Script_typed_ir.List_t sty meta)
    | Set__t {ty sty meta} :
      proj_rel ty sty
      proj_rel (Ty.Set_ ty) (Script_typed_ir.Set_t sty meta)
    | Map_t {tyk tyv styk styv meta} :
      proj_rel tyk styk
      proj_rel tyv styv
      proj_rel (Ty.Map tyk tyv) (Script_typed_ir.Map_t styk styv meta)
    | Big_map_t {tyk tyv styk styv meta} :
      proj_rel tyk styk
      proj_rel tyv styv
      proj_rel (Ty.Big_map tyk tyv) (Script_typed_ir.Big_map_t styk styv meta)
    | Contract_t {ty sty meta} :
      proj_rel ty sty
      proj_rel (Ty.Contract ty) (Script_typed_ir.Contract_t sty meta)
    | Sapling_transaction_t {memo} : proj_rel Ty.Sapling_transaction
        (Script_typed_ir.Sapling_transaction_t memo)
    | Sapling_transaction_deprecated_t {memo} :
      proj_rel Ty.Sapling_transaction_deprecated
        (Script_typed_ir.Sapling_transaction_deprecated_t memo)
    | Sapling_state_t {memo} : proj_rel Ty.Sapling_state
        (Script_typed_ir.Sapling_state_t memo)
    | Operation_t : proj_rel Ty.Operation Script_typed_ir.Operation_t
    | Chain_id_t : proj_rel Ty.Chain_id Script_typed_ir.Chain_id_t
    | Never_t : proj_rel Ty.Never Script_typed_ir.Never_t
    | Bls12_381_g1_t : proj_rel Ty.Bls12_381_g1 Script_typed_ir.Bls12_381_g1_t
    | Bls12_381_g2_t : proj_rel Ty.Bls12_381_g2 Script_typed_ir.Bls12_381_g2_t
    | Bls12_381_fr_t : proj_rel Ty.Bls12_381_fr Script_typed_ir.Bls12_381_fr_t
    | Ticket_t {ty sty meta} :
      proj_rel ty sty
      proj_rel (Ty.Ticket ty) (Script_typed_ir.Ticket_t sty meta)
    | Chest_key_t : proj_rel Ty.Chest_key Script_typed_ir.Chest_key_t
    | Chest_t : proj_rel Ty.Chest Script_typed_ir.Chest_t.

The predicate [t] above is functional. [to_Ty_t sty] computes the unique [ty] such that [t ty sty]. [to_Ty_t] is (and will probably remain) surjective in Proto_alpha (Lima).
    Fixpoint to_Ty_t (ty : Script_typed_ir.ty) : Ty.t :=
      match ty with
      | Script_typed_ir.Unit_tTy.Unit
      | Script_typed_ir.Int_tTy.Num Ty.Num.Int
      | Script_typed_ir.Nat_tTy.Num Ty.Num.Nat
      | Script_typed_ir.Signature_tTy.Signature
      | Script_typed_ir.String_tTy.String
      | Script_typed_ir.Bytes_tTy.Bytes
      | Script_typed_ir.Mutez_tTy.Mutez
      | Script_typed_ir.Key_hash_tTy.Key_hash
      | Script_typed_ir.Key_tTy.Key
      | Script_typed_ir.Timestamp_tTy.Timestamp
      | Script_typed_ir.Address_tTy.Address
      | Script_typed_ir.Tx_rollup_l2_address_tTy.Tx_rollup_l2_address
      | Script_typed_ir.Bool_tTy.Bool
      | Script_typed_ir.Pair_t ty1 ty2 meta cmp
          Ty.Pair (to_Ty_t ty1) (to_Ty_t ty2)
      | Script_typed_ir.Union_t ty1 ty2 meta cmp
          Ty.Union (to_Ty_t ty1) (to_Ty_t ty2)
      | Script_typed_ir.Lambda_t ty1 ty2 meta
          Ty.Lambda (to_Ty_t ty1) (to_Ty_t ty2)
      | Script_typed_ir.Option_t ty meta cmpTy.Option (to_Ty_t ty)
      | Script_typed_ir.List_t ty metaTy.List (to_Ty_t ty)
      | Set_t ty metaTy.Set_ (to_Ty_t ty)
      | Script_typed_ir.Map_t ty1 ty2 meta
          Ty.Map (to_Ty_t ty1) (to_Ty_t ty2)
      | Script_typed_ir.Big_map_t ty1 ty2 meta
          Ty.Big_map (to_Ty_t ty1) (to_Ty_t ty2)
      | Script_typed_ir.Contract_t ty meta
          Ty.Contract (to_Ty_t ty)
      | Script_typed_ir.Sapling_transaction_t memo
          Ty.Sapling_transaction
      | Script_typed_ir.Sapling_transaction_deprecated_t memo
          Ty.Sapling_transaction_deprecated
      | Script_typed_ir.Sapling_state_t memo
          Ty.Sapling_state
      | Script_typed_ir.Operation_tTy.Operation
      | Script_typed_ir.Chain_id_tTy.Chain_id
      | Script_typed_ir.Never_tTy.Never
      | Script_typed_ir.Bls12_381_g1_tTy.Bls12_381_g1
      | Script_typed_ir.Bls12_381_g2_tTy.Bls12_381_g2
      | Script_typed_ir.Bls12_381_fr_tTy.Bls12_381_fr
      | Script_typed_ir.Ticket_t ty meta
        Ty.Ticket (to_Ty_t ty)
      | Script_typed_ir.Chest_key_tTy.Chest_key
      | Script_typed_ir.Chest_tTy.Chest
      end.

We consider size of all [x : Script_typed_ir.ty] within the nodes are Valid, i.e. 0 <= x <= Saturation_repr.saturated.
@TODO Not sure if the predicate below really are validity predicates. @TODO When checked, define the suitable modules.
Module stack_ty.
  Module Valid.
Validity predicate for the type [stack_ty].
  Inductive t : Stack_ty.t stack_ty Prop :=
  | Item_t {ty_ rest} ty script_rest :
    ty.Valid.proj_rel ty_ ty
    t rest script_rest
    t (ty_ :: rest) (Script_typed_ir.Item_t ty script_rest)
  | Bot_t :
    t [] Script_typed_ir.Bot_t.
  End Valid.
End stack_ty.

@TODO: Every type [foo] which does not need a recursively defined predicate should be put outside module [Script_typed_ir.Valid] and put in a module [foo].
Module Valid.
Validity predicate for [stack_prefix_preservation_witness].
  Inductive stack_prefix_preservation_witness :
    Stack_ty.t Stack_ty.t Stack_ty.t Stack_ty.t
    stack_prefix_preservation_witness Prop :=
  | KPrefix : {a s t u v} loc ty witn,
      ty.Valid.proj_rel a ty
      stack_prefix_preservation_witness s t u v witn
      stack_prefix_preservation_witness s t (a :: u) (a :: v)
        (Script_typed_ir.KPrefix loc ty witn)
  | KRest : {s t}, stack_prefix_preservation_witness s t s t
                       Script_typed_ir.KRest.

Validity predicate for [comb_gadt_witness].
  Inductive comb_gadt_witness : Stack_ty.t Stack_ty.t
    comb_gadt_witness Prop :=
  | Comb_one : {s}, comb_gadt_witness s s Script_typed_ir.Comb_one
  | Comb_succ : {a b s s'} w1,
      comb_gadt_witness s (b :: s') w1
      comb_gadt_witness (a :: s) (Ty.Pair a b :: s')
        (Script_typed_ir.Comb_succ w1) .

Validity predicate for [uncomb_gadt_witness].
  Inductive uncomb_gadt_witness : Stack_ty.t Stack_ty.t
    uncomb_gadt_witness Prop :=
  | Uncomb_one : {s}, uncomb_gadt_witness s s Script_typed_ir.Uncomb_one
  | Uncomb_succ : {a b s s'} w1,
      uncomb_gadt_witness (b :: s) s' w1
      uncomb_gadt_witness (Ty.Pair a b :: s) (a :: s')
        (Script_typed_ir.Uncomb_succ w1).

Validity predicate for [comb_get_gadt_witness].
Validity predicate for [comb_set_gadt_witness].
  Inductive comb_set_gadt_witness : Ty.t Ty.t Ty.t
    comb_set_gadt_witness Prop :=
  | Comb_set_zero : {v a}, comb_set_gadt_witness v a v
      Script_typed_ir.Comb_set_zero
  | Comb_set_one : {v a b},
      comb_set_gadt_witness v (Ty.Pair a b) (Ty.Pair v b)
        Script_typed_ir.Comb_set_one
  | Comb_set_plus_two : {v a b c} w1,
      comb_set_gadt_witness v b c w1
      comb_set_gadt_witness v (Ty.Pair a b) (Ty.Pair a c)
        (Script_typed_ir.Comb_set_plus_two w1).

Validity predicate for [dup_n_gadt_witness].
  Inductive dup_n_gadt_witness : Stack_ty.t Ty.t
    dup_n_gadt_witness Prop :=
  | Dup_n_zero : {a s}, dup_n_gadt_witness (a :: s) a
      (Script_typed_ir.Dup_n_zero)
  | Dup_n_succ : {a b s} w1, dup_n_gadt_witness s b w1
      dup_n_gadt_witness (a :: s) b (Script_typed_ir.Dup_n_succ w1).

Validity predicate for [view_signature].
  Inductive view_signature : Ty.t Ty.t view_signature Prop :=
  | View_signature {a b} name tya tyb :
    (* input_ty *)
    ty.Valid.proj_rel a tya
    (* output_ty *)
    ty.Valid.proj_rel b tyb
    view_signature a b
      (Script_typed_ir.View_signature
         {|
           Script_typed_ir.view_signature.View_signature.name := name;
           Script_typed_ir.view_signature.View_signature.input_ty := tya;
           Script_typed_ir.view_signature.View_signature.output_ty := tyb;
         |}).

  Reserved Notation "'Script_Map".

The predicate [kinstr st1 st2 k] specifies that the instruction [k] is valid and produces the stack [st2] from the stack [st1]. @TODO add the suitable validity condition, e.g. comparability and so on. For the future, it could be useful to---if possible: Define a validity predicate with [st1] and [k] as sole variables. Define a function computing [st2] from [st1] and [k], when [st1] are valid. Prove that this function outputs a valid [st2]. This would in particular prove that [Michelson] specifies a unique [st2] when [st1] and [st2] are given.
  #[bypass_check(positivity=yes)]
  Inductive kinstr : Stack_ty.t Stack_ty.t Script_typed_ir.kinstr Prop :=
  (*
     Stack
     -----
   *)

  | IDrop {a s f} loc k :
    kinstr s f k
    kinstr (a :: s) f (Script_typed_ir.IDrop loc k)
  | IDup {a s f} loc k :
    kinstr (a :: a :: s) f k
    kinstr (a :: s) f (Script_typed_ir.IDup loc k)
  | ISwap {a b s f} loc k :
    kinstr (b :: a :: s) f k
    kinstr (a :: b ::s) f (Script_typed_ir.ISwap loc k)
  | IConst {t s f} loc typ (val : Ty.to_Set t) k :
    ty.Valid.proj_rel t typ
    value t val
    kinstr (t :: s) f k
    kinstr s f (Script_typed_ir.IConst loc typ val k)
  (*
     Pairs
     -----
   *)

  | ICons_pair {a b s f} loc k :
    kinstr (Ty.Pair a b :: s) f k
    kinstr (a :: b :: s) f (Script_typed_ir.ICons_pair loc k)
  | ICar {a b s f} loc k :
    kinstr (a::s) f k
    kinstr (Ty.Pair a b :: s) f (Script_typed_ir.ICar loc k)
  | ICdr {a b s f} loc k :
    kinstr (b :: s) f k
    kinstr (Ty.Pair a b :: s) f (Script_typed_ir.ICdr loc k)
  | IUnpair {a b s f} loc k :
    kinstr (a :: b :: s) f k
    kinstr (Ty.Pair a b :: s) f (Script_typed_ir.IUnpair loc k)
  (*
     Options
     -------
   *)

  | ICons_some {v s f} loc k :
    kinstr (Ty.Option v :: s) f k
    kinstr (v :: s) f (Script_typed_ir.ICons_some loc k)
  | ICons_none {b s f} loc k btyp :
    ty.Valid.proj_rel b btyp
    kinstr (Ty.Option b :: s) f k
    kinstr s f (Script_typed_ir.ICons_none loc btyp k)
  | IIf_none {a s t f} loc knone ksome k :
    kinstr s t knone
    kinstr (a::s) t ksome
    kinstr t f k
    kinstr
      (Ty.Option a :: s) f
      (Script_typed_ir.IIf_none
         {|
           Script_typed_ir.kinstr.IIf_none.loc := loc;
           Script_typed_ir.kinstr.IIf_none.branch_if_none := knone;
           Script_typed_ir.kinstr.IIf_none.branch_if_some := ksome;
           Script_typed_ir.kinstr.IIf_none.k := k;
         |})
  | IOpt_map {a b s t} loc kbody k :
    kinstr (a :: s) (b :: s) kbody
    kinstr (Ty.Option b :: s) t k
    kinstr
      (Ty.Option a :: s) t
      (Script_typed_ir.IOpt_map
         {|
           Script_typed_ir.kinstr.IOpt_map.loc := loc;
           Script_typed_ir.kinstr.IOpt_map.body := kbody;
           Script_typed_ir.kinstr.IOpt_map.k := k;
         |})
  (*
     Unions
     ------
   *)

  | ICons_left {a b s f} loc bty k :
    ty.Valid.proj_rel b bty
    kinstr (Ty.Union a b :: s) f k
    kinstr (a :: s) f (Script_typed_ir.ICons_left loc bty k)
  | ICons_right {a b s f} loc aty k :
    ty.Valid.proj_rel a aty
    kinstr (Ty.Union a b :: s) f k
    kinstr (b :: s) f (Script_typed_ir.ICons_right loc aty k)
  | IIf_left {a b s t f} loc kleft kright k :
    kinstr (a::s) t kleft
    kinstr (b::s) t kright
    kinstr t f k
    kinstr
      (Ty.Union a b :: s) f
      (Script_typed_ir.IIf_left
         {|
           Script_typed_ir.kinstr.IIf_left.loc := loc;
           Script_typed_ir.kinstr.IIf_left.branch_if_left := kleft;
           Script_typed_ir.kinstr.IIf_left.branch_if_right := kright;
           Script_typed_ir.kinstr.IIf_left.k := k;
         |})
  (*
     Lists
     -----
  *)

  | ICons_list {a s f} loc k :
    kinstr (Ty.List a :: s) f k
    kinstr (a :: Ty.List a :: s) f (Script_typed_ir.ICons_list loc k)
  | INil {b s f} loc bty k :
    ty.Valid.proj_rel b bty
    kinstr (Ty.List b :: s) f k
    kinstr s f (Script_typed_ir.ICons_list loc k)
  | IIf_cons {a s t f} loc kcons knil k :
    kinstr (a :: Ty.List a :: s) t kcons
    kinstr s t knil
    kinstr t f k
    kinstr
      (Ty.List a :: s) f
      (Script_typed_ir.IIf_cons
         {|
           Script_typed_ir.kinstr.IIf_cons.loc := loc;
           Script_typed_ir.kinstr.IIf_cons.branch_if_cons := kcons;
           Script_typed_ir.kinstr.IIf_cons.branch_if_nil := knil;
           Script_typed_ir.kinstr.IIf_cons.k := k;
         |})
  | IList_map {a b s f} loc bty k klb :
    kinstr (a :: s) (b :: s) k
    Option.Forall (ty.Valid.proj_rel (Ty.List b)) bty
    kinstr (Ty.List b :: s) f klb
    kinstr (Ty.List a :: s) f (Script_typed_ir.IList_map loc k bty klb)
  | IList_iter {a s f} loc aty k k1 :
      Option.Forall (ty.Valid.proj_rel a) aty
      kinstr (a :: s) s k
      kinstr s f k1
      kinstr (Ty.List a :: s) f (Script_typed_ir.IList_iter loc aty k k1)
  | IList_size {a s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.List a :: s) f (Script_typed_ir.IList_size loc k)
  (*
    Sets
    ----
   *)

  | IEmpty_set {a s f} loc k tya :
      ty.Valid.proj_rel a tya
      Script_family.Ty.is_Comparable a
      kinstr (Ty.Set_ a :: s) f k
      kinstr s f (Script_typed_ir.IEmpty_set loc tya k)
  | ISet_iter {a s f} loc aty k k1 :
      Script_family.Ty.is_Comparable a
      Option.Forall (ty.Valid.proj_rel a) aty
      kinstr (a :: s) s k
      kinstr s f k1
      kinstr (Ty.Set_ a :: s) f (Script_typed_ir.ISet_iter loc aty k k1)
  | ISet_mem {a s f} loc k :
      kinstr (Ty.Bool :: s) f k
      kinstr (a :: Ty.Set_ a :: s) f (Script_typed_ir.ISet_mem loc k)
  | ISet_update {a s f} loc k :
      kinstr (Ty.Set_ a :: s) f k
      kinstr (a :: Ty.Bool :: Ty.Set_ a :: s) f (Script_typed_ir.ISet_mem loc k)
  | ISet_size {a s f} loc k :
      kinstr (Ty.Num Ty.Num.Nat :: s) f k
      kinstr (Ty.Set_ a :: s) f (Script_typed_ir.ISet_size loc k)
  (*
     Maps
     ----
   *)

  | IEmpty_map {b c s f} loc tyb tyc k :
    ty.Valid.proj_rel b tyb
    Script_family.Ty.is_Comparable b
    Option.Forall (ty.Valid.proj_rel c) tyc
    kinstr (Ty.Map b c :: s) f k
    kinstr s f (Script_typed_ir.IEmpty_map loc tyb tyc k)
  | IMap_map {a b c s f} loc ty k1 k2 :
    Option.Forall (ty.Valid.proj_rel (Ty.Map a c)) ty
    kinstr (Ty.Pair a b :: s) (c :: s) k1
    kinstr (Ty.Map a c :: s) f k2
    kinstr (Ty.Map a b :: s) f (Script_typed_ir.IMap_map loc ty k1 k2)
  | IMap_iter {a b s f} loc ty k1 k2 :
    Option.Forall (ty.Valid.proj_rel (Ty.Pair a b)) ty
    kinstr (Ty.Pair a b :: s) s k1
    kinstr s f k2
    kinstr (Ty.Map a b :: s) f (Script_typed_ir.IMap_iter loc ty k1 k2)
  | IMap_mem {a b s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (a :: Ty.Map a b :: s) f (Script_typed_ir.IMap_mem loc k)
  | IMap_get {a b s f} loc k :
    kinstr (Ty.Option b :: s) f k
    kinstr (a :: Ty.Map a b :: s) f (Script_typed_ir.IMap_get loc k)
  | IMap_update {a b s f} loc k :
    kinstr (Ty.Map a b :: s) f k
    kinstr (a :: Ty.Option b :: Ty.Map a b :: s) f (Script_typed_ir.IMap_update loc k)
  | IMap_get_and_update {a b s f} loc k :
    kinstr (Ty.Option b :: Ty.Map a b :: s) f k
    kinstr (a :: Ty.Option b :: Ty.Map a b :: s) f (Script_typed_ir.IMap_get_and_update loc k)
  | IMap_size {a b s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Map a b :: s) f (Script_typed_ir.IMap_size loc k)
  (*
     Big maps
     --------
  *)

  | IEmpty_big_map {b c s f} loc bty cty k :
    ty.Valid.proj_rel b bty
    ty.Valid.proj_rel c cty
    Script_family.Ty.is_Comparable b
    kinstr (Ty.Big_map b c :: s) f k
    kinstr s f (Script_typed_ir.IEmpty_big_map loc bty cty k)
  | IBig_map_mem {a b s f} loc k :
    Alpha_context.Script.location
    kinstr (Ty.Bool :: s) f k
    kinstr (a :: (Ty.Big_map a b) :: s) f (Script_typed_ir.IBig_map_mem loc k)
  | IBig_map_get {a b s f} loc k :
    Alpha_context.Script.location
    kinstr (Ty.Option b :: s) f k
    kinstr (a :: Ty.Big_map a b :: s) f (Script_typed_ir.IBig_map_get loc k)
  | IBig_map_update {a b s f} loc k :
    kinstr (Ty.Big_map a b :: s) f k
    kinstr
      (a :: Ty.Option b :: Ty.Big_map a b :: s) f
      (Script_typed_ir.IBig_map_get loc k)
  | IBig_map_get_and_update {a b s f} loc k :
    kinstr (Ty.Option b :: Ty.Big_map a b :: s) f k
    kinstr
      (a :: Ty.Option b :: Ty.Big_map a b :: s) f
      (Script_typed_ir.IBig_map_get_and_update loc k)
  (*
     Strings
     -------
   *)

  | IConcat_string {s f} loc k :
    kinstr (Ty.String :: s) f k
    kinstr (Ty.List Ty.String :: s) f (Script_typed_ir.IConcat_string loc k)
  | IConcat_string_pair {s f} loc k :
    kinstr (Ty.String :: s) f k
    kinstr (Ty.String :: Ty.String :: s) f
      (Script_typed_ir.IConcat_string_pair loc k)
  | ISlice_string {s f} loc k :
    kinstr (Ty.Option Ty.String :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num Ty.Num.Nat :: Ty.String :: s) f
      (Script_typed_ir.ISlice_string loc k)
  | IString_size {s f} loc k :
    Alpha_context.Script.location
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.String :: s) f (Script_typed_ir.IString_size loc k)
  (*
     Bytes
     -----
   *)

  | IConcat_bytes {s f} loc k :
    kinstr (Ty.Bytes :: s) f k
    kinstr (Ty.List Ty.Bytes :: s) f (Script_typed_ir.IConcat_bytes loc k)
  | IConcat_bytes_pair {s f} loc k :
    kinstr (Ty.Bytes :: s) f k
    kinstr (Ty.Bytes :: Ty.Bytes :: s) f (Script_typed_ir.IConcat_bytes_pair loc k)
  | ISlice_bytes {s f} loc k :
    kinstr (Ty.Option Ty.Bytes :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num Ty.Num.Nat :: Ty.Bytes :: s) f
      (Script_typed_ir.ISlice_bytes loc k)
  | IBytes_size {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Bytes :: s) f (Script_typed_ir.IBytes_size loc k)
  (*
     Timestamps
     ----------
   *)

  | IAdd_seconds_to_timestamp {s f} loc k:
    kinstr (Ty.Timestamp :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: Ty.Timestamp :: s) f
      (Script_typed_ir.IAdd_seconds_to_timestamp loc k)
  | IAdd_timestamp_to_seconds {s f} loc k :
    kinstr (Ty.Timestamp :: s) f k
    kinstr (Ty.Timestamp :: Ty.Num Ty.Num.Int :: s) f
      (Script_typed_ir.IAdd_timestamp_to_seconds loc k)
  | ISub_timestamp_seconds {s f} loc k :
    kinstr (Ty.Timestamp :: s) f k
    kinstr (Ty.Timestamp :: Ty.Num Ty.Num.Int :: s) f
      (Script_typed_ir.ISub_timestamp_seconds loc k)
  | IDiff_timestamps {s f} loc k :
    kinstr (Ty.Num Ty.Num.Int :: s) f k
    kinstr (Ty.Timestamp :: Ty.Timestamp :: s) f
      (Script_typed_ir.IDiff_timestamps loc k)
  (*
     Tez
     ---
   *)

  | IAdd_tez {s f} loc k :
    kinstr (Ty.Mutez :: s) f k
    kinstr (Ty.Mutez :: Ty.Mutez :: s) f (Script_typed_ir.IAdd_tez loc k)
  | ISub_tez {s f} loc k :
    kinstr (Ty.Option Ty.Mutez :: s) f k
    kinstr (Ty.Mutez :: Ty.Mutez :: s) f (Script_typed_ir.ISub_tez loc k)
  | ISub_tez_legacy {s f} loc k :
    kinstr (Ty.Mutez :: s) f k
    kinstr (Ty.Mutez :: Ty.Mutez :: s) f (Script_typed_ir.ISub_tez_legacy loc k)
  | IMul_teznat {s f} loc k :
    kinstr (Ty.Mutez :: s) f k
    kinstr (Ty.Mutez :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.IMul_teznat loc k)
  | IMul_nattez {s f} loc k :
    kinstr (Ty.Mutez :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Mutez :: s) f
      (Script_typed_ir.IMul_nattez loc k)
  | IEdiv_teznat {s f} loc k :
    kinstr (Ty.Option (Ty.Pair Ty.Mutez Ty.Mutez) :: s) f k
    kinstr (Ty.Mutez :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.IEdiv_teznat loc k)
  | IEdiv_tez {s f} loc k :
    kinstr (Ty.Option (Ty.Pair (Ty.Num Ty.Num.Nat) Ty.Mutez) :: s) f k
    kinstr (Ty.Mutez :: Ty.Mutez :: s) f
      (Script_typed_ir.IEdiv_tez loc k)
  (*
    Booleans
    --------
   *)

  | IOr {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Bool :: Ty.Bool :: s) f (Script_typed_ir.IOr loc k)
  | IAnd {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Bool :: Ty.Bool :: s) f (Script_typed_ir.IAnd loc k)
  | IXor {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Bool :: Ty.Bool :: s) f (Script_typed_ir.IXor loc k)
  | INot {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Bool :: s) f (Script_typed_ir.INot loc k)
  (*
     Integers
     --------
  *)

  | IIs_nat {s f} loc k :
    kinstr (Ty.Option (Ty.Num Ty.Num.Nat) :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: s) f (Script_typed_ir.IIs_nat loc k)
  | INeg {a s f} loc k :
    kinstr (Ty.Num Ty.Num.Int :: s) f k
    kinstr (Ty.Num a :: s) f (Script_typed_ir.INeg loc k)
  | IAbs_int {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: s) f (Script_typed_ir.IAbs_int loc k)
  | IInt_nat {s f} loc k :
    kinstr (Ty.Num Ty.Num.Int :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: s) f (Script_typed_ir.IInt_nat loc k)
  | IAdd_int {a b s f} loc k :
    kinstr (Ty.Num Ty.Num.Int :: s) f k
    kinstr (Ty.Num a :: Ty.Num b :: s) f (Script_typed_ir.IAdd_int loc k)
  | IAdd_nat {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.IAdd_nat loc k)
  | ISub_int {a b s f} loc k :
    kinstr (Ty.Num Ty.Num.Int :: s) f k
    kinstr (Ty.Num a :: Ty.Num b :: s) f (Script_typed_ir.ISub_int loc k)
  | IMul_int {a b s f} loc k :
    kinstr (Ty.Num Ty.Num.Int :: s) f k
    kinstr (Ty.Num a :: Ty.Num b :: s) f (Script_typed_ir.IMul_int loc k)
  | IMul_nat {a s f} loc k :
    kinstr (Ty.Num a :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num a :: s) f
      (Script_typed_ir.IMul_nat loc k)
  | IEdiv_int {a b s f} loc k :
    kinstr
      (Ty.Option (Ty.Pair (Ty.Num Ty.Num.Int) (Ty.Num Ty.Num.Nat)) :: s) f k
    kinstr (Ty.Num a :: Ty.Num b :: s) f (Script_typed_ir.IEdiv_int loc k)
  | IEdiv_nat {a s f} loc k :
    kinstr (Ty.Option (Ty.Pair (Ty.Num a) (Ty.Num Ty.Num.Nat)) :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num a :: s) f
      (Script_typed_ir.IEdiv_nat loc k)
  | ILsl_nat {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.ILsl_nat loc k)
  | ILsr_nat {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.ILsr_nat loc k)
  | IOr_nat {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.IOr_nat loc k)
  | IAnd_nat {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.IAnd_nat loc k)
  | IAnd_int_nat {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.IAnd_int_nat loc k)
  | IXor_nat {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Num Ty.Num.Nat :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.IXor_nat loc k)
  | INot_int {a s f} loc k :
    kinstr (Ty.Num Ty.Num.Int :: s) f k
    kinstr (Ty.Num a :: s) f (Script_typed_ir.INot_int loc k)
  (*
    Control
    -------
   *)

  | IIf {s u f} loc k k1 k2 :
    kinstr s u k1
    kinstr s u k2
    kinstr u f k
    kinstr (Ty.Bool :: s) f
    (Script_typed_ir.IIf
       {|
         Script_typed_ir.kinstr.IIf.loc := loc;
         Script_typed_ir.kinstr.IIf.branch_if_true := k1;
         Script_typed_ir.kinstr.IIf.branch_if_false := k2;
         Script_typed_ir.kinstr.IIf.k := k;
       |})
   | ILoop {s f} loc k1 k2:
     kinstr s (Ty.Bool :: s) k1
     kinstr s f k2
     kinstr (Ty.Bool :: s) f (Script_typed_ir.ILoop loc k1 k2)
  | ILoop_left {a b s f} loc k1 k2 :
    kinstr (a :: s) (Ty.Union a b :: s) k1
    kinstr (b :: s) f k2
    kinstr (Ty.Union a b :: s) f (Script_typed_ir.ILoop_left loc k1 k2)
  | IDip {a s t f} loc ty k1 k2 :
    kinstr s t k1
    Option.Forall (ty.Valid.proj_rel a) ty
    kinstr (a :: t) f k2
    kinstr (a :: s) f (Script_typed_ir.IDip loc k1 ty k2)
  | IExec {a b s f} loc script_stack k :
    Option.Forall (stack_ty.Valid.t (b :: s)) script_stack
    kinstr (b :: s) f k
    kinstr (a :: Ty.Lambda a b :: s) f (Script_typed_ir.IExec loc script_stack k)
  | IApply {a b c s f} loc ty k :
    ty.Valid.proj_rel b ty
    kinstr (Ty.Lambda b c :: s) f k
    kinstr (a :: Ty.Lambda (Ty.Pair a b) c :: s) f
      (Script_typed_ir.IApply loc ty k)
  | ILambda {s b c f} loc lmbd k :
    kinstr (Ty.Lambda b c :: s) f k
    kinstr s f (Script_typed_ir.ILambda loc lmbd k)
  | IFailwith {a s f} loc ty :
    ty.Valid.proj_rel a ty
    kinstr (a :: s) f (Script_typed_ir.IFailwith loc ty)
  (*
     Comparison
     ----------
  *)

  | ICompare {a s f} loc ty k :
    ty.Valid.proj_rel a ty
    kinstr (Ty.Num Ty.Num.Int :: s) f k
    kinstr (a :: a :: s) f (Script_typed_ir.ICompare loc ty k)
  (*
     Comparators
     -----------
  *)

  | IEq {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: s) f (Script_typed_ir.IEq loc k)
  | INeq {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: s) f (Script_typed_ir.INeq loc k)
  | ILt {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: s) f (Script_typed_ir.ILt loc k)
  | IGt {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: s) f (Script_typed_ir.IGt loc k)
  | ILe {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: s) f (Script_typed_ir.ILe loc k)
  | IGe {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Num Ty.Num.Int :: s) f (Script_typed_ir.IGe loc k)
  (*
     Protocol
     --------
  *)

  | IAddress {a s f} loc k :
    kinstr (Ty.Address :: s) f k
    kinstr (Ty.Contract a :: s) f (Script_typed_ir.IAddress loc k)
  | IContract {a s f} loc ty str k :
    ty.Valid.proj_rel a ty
    kinstr (Ty.Option (Ty.Contract a) :: s) f k
    kinstr (Ty.Address :: s) f (Script_typed_ir.IContract loc ty str k)
  | IView {a b s f} loc sig s_stack k :
    view_signature a b sig
    Option.Forall (stack_ty.Valid.t (b :: s)) s_stack
    kinstr (Ty.Option b :: s) f k
    kinstr (a :: Ty.Address :: s) f (Script_typed_ir.IView loc sig s_stack k)
  | ITransfer_tokens {a s f} loc k :
    kinstr (Ty.Operation :: s) f k
    kinstr (a :: Ty.Mutez :: Ty.Contract a :: s) f
      (Script_typed_ir.ITransfer_tokens loc k)
  | IImplicit_account {s f} loc k :
    kinstr (Ty.Contract Ty.Unit :: s) f k
    kinstr (Ty.Key_hash :: s) f (Script_typed_ir.IImplicit_account loc k)
  | ICreate_contract {a s f} loc ty expr k :
    ty.Valid.proj_rel a ty
    Alpha_context.Script.expr
    kinstr (Ty.Operation :: Ty.Address :: s) f k
    kinstr (Ty.Option Ty.Key_hash :: Ty.Mutez :: a :: s) f
      (Script_typed_ir.ICreate_contract
         {|
           Script_typed_ir.kinstr.ICreate_contract.loc := loc;
           Script_typed_ir.kinstr.ICreate_contract.storage_type := ty;
           Script_typed_ir.kinstr.ICreate_contract.code := expr;
           Script_typed_ir.kinstr.ICreate_contract.k := k;
         |})
  | ISet_delegate {s f} loc k :
    kinstr (Ty.Operation :: s) f k
    kinstr (Ty.Option Ty.Key_hash :: s) f (Script_typed_ir.ISet_delegate loc k)
  | INow {s f} loc k :
    kinstr (Ty.Timestamp :: s) f k
    kinstr s f (Script_typed_ir.INow loc k)
  | IMin_block_time {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr s f (Script_typed_ir.IMin_block_time loc k)
  | IBalance {s f} loc k :
    kinstr (Ty.Mutez :: s) f k
    kinstr s f (Script_typed_ir.IBalance loc k)
  | ILevel {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr s f (Script_typed_ir.ILevel loc k)
  | ICheck_signature {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.Key :: Ty.Signature :: Ty.Bytes :: s) f
      (Script_typed_ir.ICheck_signature loc k)
  | IHash_key {s f} loc k :
    kinstr (Ty.Key_hash :: s) f k
    kinstr (Ty.Key :: s) f (Script_typed_ir.IHash_key loc k)
  | IPack {a s f} loc ty k :
    ty.Valid.proj_rel a ty
    kinstr (Ty.Bytes :: s) f k
    kinstr (a :: s) f (Script_typed_ir.IPack loc ty k)
  | IUnpack {a s f} loc ty k :
    Alpha_context.Script.location
    ty.Valid.proj_rel a ty
    kinstr (Ty.Option a :: s) f k
    kinstr (Ty.Bytes :: s) f (Script_typed_ir.IUnpack loc ty k)
  | IBlake2b {s f} loc k :
    kinstr (Ty.Bytes :: s) f k
    kinstr (Ty.Bytes :: s) f (Script_typed_ir.IBlake2b loc k)
  | ISha256 {s f} loc k :
    kinstr (Ty.Bytes :: s) f k
    kinstr (Ty.Bytes :: s) f (Script_typed_ir.ISha256 loc k)
  | ISha512 {s f} loc k :
    kinstr (Ty.Bytes :: s) f k
    kinstr (Ty.Bytes :: s) f (Script_typed_ir.ISha512 loc k)
  | ISource {s f} loc k :
    kinstr (Ty.Address :: s) f k
    kinstr s f (Script_typed_ir.ISource loc k)
  | ISender {s f} loc k :
    kinstr (Ty.Address :: s) f k
    kinstr s f (Script_typed_ir.ISender loc k)
  | ISelf {b s f} loc ty str k :
    ty.Valid.proj_rel b ty
    kinstr (Ty.Contract b :: s) f k
    kinstr s f (Script_typed_ir.ISelf loc ty str k)
  | ISelf_address {s f} loc k :
    kinstr (Ty.Address :: s) f k
    kinstr s f (Script_typed_ir.ISelf_address loc k)
  | IAmount {s f} loc k :
    kinstr (Ty.Mutez :: s) f k
    kinstr s f (Script_typed_ir.IAmount loc k)
  | ISapling_empty_state {s f} loc memo_size k :
    Alpha_context.Sapling.Memo_size.t
    kinstr (Ty.Sapling_state :: s) f k
    kinstr s f (Script_typed_ir.ISapling_empty_state loc memo_size k)
  | ISapling_verify_update {s f} loc k :
    kinstr
      (Ty.Option (Ty.Pair
        Ty.Bytes
        (Ty.Pair (Ty.Num Ty.Num.Int) Ty.Sapling_state)) ::
        s)
      f k
    kinstr (Ty.Sapling_transaction :: Ty.Sapling_state :: s) f
      (Script_typed_ir.ISapling_verify_update loc k)
  | ISapling_verify_update_deprecated {s f} loc k :
    kinstr
      (Ty.Option (Ty.Pair (Ty.Num Ty.Num.Int) Ty.Sapling_state) :: s)
      f k
    kinstr (Ty.Sapling_transaction_deprecated :: Ty.Sapling_state :: s) f
      (Script_typed_ir.ISapling_verify_update_deprecated loc k)
  | IDig {a s t u f} loc i witness k :
    stack_prefix_preservation_witness (a :: s) s t u witness
    kinstr (a :: u) f k
    kinstr t f (Script_typed_ir.IDig loc i witness k)
  | IDug {a s t u f} loc i witness k :
    stack_prefix_preservation_witness s (a :: s) t u witness
    kinstr u f k
    kinstr (a :: t) f (Script_typed_ir.IDug loc i witness k)
  | IDipn {s t u v f} loc i witness k1 k2:
    stack_prefix_preservation_witness t v s u witness
    kinstr t v k1
    kinstr u f k2
    kinstr s f (Script_typed_ir.IDipn loc i witness k1 k2)
  | IDropn {s u f} loc i witness k :
    stack_prefix_preservation_witness u u s s witness
    kinstr u f k
    kinstr s f (Script_typed_ir.IDropn loc i witness k)
  | IChainId {s f} loc k :
    kinstr (Ty.Chain_id :: s) f k
    kinstr s f (Script_typed_ir.IChainId loc k)
  | INever {s f} loc :
    kinstr (Ty.Never :: s) f (Script_typed_ir.INever loc)
  | IVoting_power {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr (Ty.Key_hash :: s) f (Script_typed_ir.IVoting_power loc k)
  | ITotal_voting_power {s f} loc k :
    kinstr (Ty.Num Ty.Num.Nat :: s) f k
    kinstr s f (Script_typed_ir.ITotal_voting_power loc k)
  | IKeccak {s f} loc k :
    kinstr (Ty.Bytes :: s) f k
    kinstr (Ty.Bytes :: s) f (Script_typed_ir.IKeccak loc k)
  | ISha3 {s f} loc k :
    kinstr (Ty.Bytes :: s) f k
    kinstr (Ty.Bytes :: s) f (Script_typed_ir.ISha3 loc k)
  | IAdd_bls12_381_g1 {s f} loc k :
    kinstr (Ty.Bls12_381_g1 :: s) f k
    kinstr (Ty.Bls12_381_g1 :: Ty.Bls12_381_g1 :: s) f
      (Script_typed_ir.IAdd_bls12_381_g1 loc k)
  | IAdd_bls12_381_g2 {s f} loc k :
    kinstr (Ty.Bls12_381_g2 :: s) f k
    kinstr (Ty.Bls12_381_g2 :: Ty.Bls12_381_g2 :: s) f
      (Script_typed_ir.IAdd_bls12_381_g2 loc k)
  | IAdd_bls12_381_fr {s f} loc k :
    kinstr (Ty.Bls12_381_fr :: s) f k
    kinstr (Ty.Bls12_381_fr :: Ty.Bls12_381_fr :: s) f
     (Script_typed_ir.IAdd_bls12_381_fr loc k)
  | IMul_bls12_381_g1 {s f} loc k :
    kinstr (Ty.Bls12_381_g1 :: s) f k
    kinstr (Ty.Bls12_381_g1 :: Ty.Bls12_381_fr :: s) f
      (Script_typed_ir.IMul_bls12_381_g1 loc k)
  | IMul_bls12_381_g2 {s f} loc k :
    kinstr (Ty.Bls12_381_g2 :: s) f k
    kinstr (Ty.Bls12_381_g2 :: Ty.Bls12_381_fr :: s) f
      (Script_typed_ir.IMul_bls12_381_g2 loc k)
  | IMul_bls12_381_fr {s f} loc k :
    kinstr (Ty.Bls12_381_fr :: s) f k
    kinstr (Ty.Bls12_381_fr :: Ty.Bls12_381_fr :: s) f
      (Script_typed_ir.IMul_bls12_381_fr loc k)
  | IMul_bls12_381_z_fr {a s f} loc k :
    kinstr (Ty.Bls12_381_fr :: s) f k
    kinstr (Ty.Bls12_381_fr :: Ty.Num a :: s) f
      (Script_typed_ir.IMul_bls12_381_z_fr loc k)
  | IMul_bls12_381_fr_z {a s f} loc k :
    kinstr (Ty.Bls12_381_fr :: s) f k
    kinstr (Ty.Num a :: Ty.Bls12_381_fr :: s) f
      (Script_typed_ir.IMul_bls12_381_fr_z loc k)
  | IInt_bls12_381_fr {s f} loc k :
    kinstr (Ty.Num Ty.Num.Int :: s) f k
    kinstr (Ty.Bls12_381_fr :: s) f (Script_typed_ir.IInt_bls12_381_fr loc k)
  | INeg_bls12_381_g1 {s f} loc k :
    kinstr (Ty.Bls12_381_g1 :: s) f k
    kinstr (Ty.Bls12_381_g1 :: s) f (Script_typed_ir.INeg_bls12_381_g1 loc k)
  | INeg_bls12_381_g2 {s f} loc k :
    kinstr (Ty.Bls12_381_g2 :: s) f k
    kinstr (Ty.Bls12_381_g2 :: s) f (Script_typed_ir.INeg_bls12_381_g2 loc k)
  | INeg_bls12_381_fr {s f} loc k :
    kinstr (Ty.Bls12_381_fr :: s) f k
    kinstr (Ty.Bls12_381_fr :: s) f (Script_typed_ir.INeg_bls12_381_fr loc k)
  | IPairing_check_bls12_381 {s f} loc k :
    kinstr (Ty.Bool :: s) f k
    kinstr (Ty.List (Ty.Pair Ty.Bls12_381_g1 Ty.Bls12_381_g2) :: s) f
      (Script_typed_ir.IPairing_check_bls12_381 loc k)
  | IComb {s u f} loc i witness k :
    comb_gadt_witness s u witness
    kinstr u f k
    kinstr s f (Script_typed_ir.IComb loc i witness k)
  | IUncomb {s u f} loc i witness k :
    uncomb_gadt_witness s u witness
    kinstr u f k
    kinstr s f (Script_typed_ir.IUncomb loc i witness k)
  | IComb_get {s t v f} loc i witness k :
    comb_get_gadt_witness t v witness
    kinstr (v :: s) f k
    kinstr (t :: s) f (Script_typed_ir.IComb_get loc i witness k)
  | IComb_set {a b c s f} loc i witness k :
    comb_set_gadt_witness a b c witness
    kinstr (c :: s) f k
    kinstr (a :: b :: s) f (Script_typed_ir.IComb_set loc i witness k)
  | IDup_n {s t f} loc i k witness :
    dup_n_gadt_witness s t witness
    kinstr (t :: s) f k
    kinstr s f (Script_typed_ir.IDup_n loc i witness k)
  | ITicket {a s f} loc ty k :
    Option.Forall (ty.Valid.proj_rel a) ty
    kinstr (Ty.Ticket a :: s) f k
    kinstr (a :: Ty.Num Ty.Num.Nat :: s) f (Script_typed_ir.ITicket loc ty k)
  | IRead_ticket {a s f} loc ty k :
    Option.Forall (ty.Valid.proj_rel a) ty
    kinstr
      (Ty.Pair Ty.Address (Ty.Pair a (Ty.Num Ty.Num.Nat)) ::
        Ty.Ticket a ::
        s) f k
    kinstr (Ty.Ticket a :: s) f (Script_typed_ir.IRead_ticket loc ty k)
  | ISplit_ticket {a s f} loc k :
    kinstr (Ty.Option (Ty.Pair (Ty.Ticket a) (Ty.Ticket a)) :: s) f k
    kinstr (Ty.Ticket a :: (Ty.Pair (Ty.Num Ty.Num.Nat) (Ty.Num Ty.Num.Nat)) :: s)
      f (Script_typed_ir.ISplit_ticket loc k)
  | IJoin_tickets {a s f} loc ty k :
    ty.Valid.proj_rel a ty
    kinstr (Ty.Option (Ty.Ticket a) :: s) f k
    kinstr (Ty.Pair (Ty.Ticket a) (Ty.Ticket a) :: s) f
      (Script_typed_ir.IJoin_tickets loc ty k)
  | IOpen_chest {s f} loc k :
    kinstr (Ty.Union Ty.Bytes Ty.Bool :: s) f k
    kinstr (Ty.Chest_key :: Ty.Chest :: Ty.Num Ty.Num.Nat :: s) f
      (Script_typed_ir.IOpen_chest loc k)
  | IEmit {a s f} loc tag ty expr k :
    ty.Valid.proj_rel a ty
    kinstr s f
      (Script_typed_ir.IEmit
      {|
         Script_typed_ir.kinstr.IEmit.loc := loc;
         Script_typed_ir.kinstr.IEmit.tag := tag;
         Script_typed_ir.kinstr.IEmit.ty := ty;
         Script_typed_ir.kinstr.IEmit.unparsed_ty := expr;
         Script_typed_ir.kinstr.IEmit.k := k;
       |})
  (*
    Internal control instructions
    -----------------------------
  *)

  | IHalt {s} loc :
    kinstr s s (Script_typed_ir.IHalt loc)

  (* We choose to ignore the [ILog] function. *)

  
Validity predicate for [value].
  with value : (t : Ty.t), Ty.to_Set t Prop :=
  | Unit_value u : value Ty.Unit u
  | Num_Int_value num_int : value (Ty.Num Ty.Num.Int) num_int
  | Num_Nat_value num_nat : value (Ty.Num Ty.Num.Nat) num_nat
  | Signature_value s : value Ty.Signature s
  | String_value s : value Ty.String s
  | Bytes_value b : value Ty.Bytes b
  | Mutez_value m : value Ty.Mutez m
  | Key_hash_value k : value Ty.Key_hash k
  | Key_value k : value Ty.Key k
  | Timestamp_value s : value Ty.Timestamp s
  | Address_value s : value Ty.Address s
  | Tx_rollup_l2_address_value tx :
      Indexable.Value.Valid.t tx
      value Ty.Tx_rollup_l2_address tx
  | Bool_value b : value Ty.Bool b
  | Pair_value a aty b bty : value a aty value b bty
      value (Ty.Pair a b) (aty, bty)
  | Union_valueL l r lty : value l lty value (Ty.Union l r)
      (Script_typed_ir.L lty)
  | Union_valueR l r rty : value r rty value (Ty.Union l r)
      (Script_typed_ir.R rty)
  | Lambda_value_Lam kd node arg ret : kdescr [arg] [ret] kd
      value (Ty.Lambda arg ret) (Script_typed_ir.Lam kd node)
  | Lambda_value_LamRec k_descr node arg ret :
    kdescr [arg ; Ty.Lambda arg ret] [ret] k_descr
      value (Ty.Lambda arg ret) (Script_typed_ir.LamRec k_descr node)
  | Option_Some_value o oty : value o oty value (Ty.Option o) (Some oty)
  | Option_None_value o oty : value o oty value (Ty.Option o) None
  | List_Nil_value l : value (Ty.List l)
      {| Script_list.t.elements := nil;
         Script_list.t.length := 0; |}
  | List_Cons_value l xs x n :
    value l x
    value (Ty.List l)
      {| Script_list.t.elements := xs;
         Script_list.t.length := n; |}
    value (Ty.List l)
      {| Script_list.t.elements := cons x xs;
         Script_list.t.length := (1 + n)%Z; |}
  | Set_value k kty :
    let _Set :=
      _Set.Make {|
        Compare.COMPARABLE.compare :=
          Script_comparable.compare_comparable kty;
      |} in
     (x : _Set.(_Set.S.t)),
    ty.Valid.proj_rel k kty
    List.Forall (fun '(key, _)value k key) x
    let OPS := {|
      Script_typed_ir.Boxed_set_OPS.elt_size :=
        Gas_comparable_input_size.size_of_comparable_value kty;
      Script_typed_ir.Boxed_set_OPS.empty := _Set.(_Set.S.empty);
      Script_typed_ir.Boxed_set_OPS.add := _Set.(_Set.S.add);
      Script_typed_ir.Boxed_set_OPS.mem := _Set.(_Set.S.mem);
      Script_typed_ir.Boxed_set_OPS.remove := _Set.(_Set.S.remove);
      Script_typed_ir.Boxed_set_OPS.fold _ := _Set.(_Set.S.fold);
    |} in
    let s := Script_typed_ir.Set_tag (existS _ _ {|
      Script_typed_ir.Boxed_set.OPS := OPS;
      Script_typed_ir.Boxed_set.boxed := x;
      Script_typed_ir.Boxed_set.size_value := _Set.(_Set.S.cardinal) x;
    |}) in
    value (Ty.Set_ k) s
  | Map_value k tyk v (k_cmp : ty.Comparable.t tyk) (k_tyk : ty.Valid.proj_rel k tyk) :
    let Map := 'Script_Map k tyk k_cmp k_tyk in
     (m : Map.(Map.S.t) (Ty.to_Set v)),
    let OPS := {|
      Script_typed_ir.Boxed_map_OPS.key_size :=
        Gas_comparable_input_size.size_of_comparable_value tyk;
      Script_typed_ir.Boxed_map_OPS.empty _ := Map.(Map.S.empty);
      Script_typed_ir.Boxed_map_OPS.add _ := Map.(Map.S.add);
      Script_typed_ir.Boxed_map_OPS.remove _ := Map.(Map.S.remove);
      Script_typed_ir.Boxed_map_OPS.find _ := Map.(Map.S.find);
      Script_typed_ir.Boxed_map_OPS.fold _ _ := Map.(Map.S.fold);
      Script_typed_ir.Boxed_map_OPS.fold_es _ _ := Map.(Map.S.fold_es);
    |} in
    let map := Script_typed_ir.Map_tag (existS _ _ {|
      Script_typed_ir.Boxed_map.OPS := OPS;
      Script_typed_ir.Boxed_map.boxed := m;
      Script_typed_ir.Boxed_map.size_value := Map.(Map.S.cardinal) m;
      Script_typed_ir.Boxed_map.boxed_map_tag := tt;
    |}) in
    value (Ty.Map k v) map
  | Big_map_value k v
      (id : option Alpha_context.Big_map.Id.t)
      key_type
      value_type
      (map :
        Script_typed_ir.Big_map_overlay.(Map.S.t)
          (Ty.to_Set k × option (Ty.to_Set v)))
      (size : int)
    : ty.Valid.proj_rel k key_type
      ty.Valid.proj_rel v value_type
      let diff := {|
        Script_typed_ir.big_map_overlay.map := map;
        Script_typed_ir.big_map_overlay.size := size;
      |} in
      value
        (Ty.Big_map k v)
        (Script_typed_ir.Big_map
           (key := Ty.to_Set k)
           (value := Ty.to_Set v)
           {|
             Script_typed_ir.big_map.Big_map.id := id;
             Script_typed_ir.big_map.Big_map.diff := diff;
             Script_typed_ir.big_map.Big_map.key_type := key_type;
             Script_typed_ir.big_map.Big_map.value_type := value_type;
           |})
  | Contract_typed_implicit_value hash : value (Ty.Contract Ty.Unit)
      (Script_typed_ir.Typed_implicit hash)
  | Contract_typed_originated_value a tya hash entry:
      ty.Valid.proj_rel a tya
      value (Ty.Contract a)
      (Script_typed_ir.Typed_originated {|
        Script_typed_ir.typed_contract.Typed_originated.arg_ty := tya ;
        Script_typed_ir.typed_contract.Typed_originated.contract_hash :=
        hash ;
        Script_typed_ir.typed_contract.Typed_originated.entrypoint := entry
      |})
  | Contract_Typed_tx_rollup_value a tya tx_rollup :
    ty.Valid.proj_rel (Ty.Pair (Ty.Ticket a) Ty.Tx_rollup_l2_address) tya
    value (Ty.Contract (Ty.Pair (Ty.Ticket a) Ty.Tx_rollup_l2_address))
      (Script_typed_ir.Typed_tx_rollup {|
       Script_typed_ir.typed_contract.Typed_tx_rollup.arg_ty := tya ;
       Script_typed_ir.typed_contract.Typed_tx_rollup.tx_rollup := tx_rollup
      |})
  | Contract_typed_sc_rollup_value a tya sc_rollup entrypoint :
    ty.Valid.proj_rel a tya
    value (Ty.Contract a) (Script_typed_ir.Typed_sc_rollup {|
      Script_typed_ir.typed_contract.Typed_sc_rollup.arg_ty := tya ;
      Script_typed_ir.typed_contract.Typed_sc_rollup.sc_rollup := sc_rollup ;
      Script_typed_ir.typed_contract.Typed_sc_rollup.entrypoint := entrypoint
    |})
  | Contract_typed_zk_rollup_value a tya zk_rollup :
    ty.Valid.proj_rel a tya
    value (Ty.Contract a) (Script_typed_ir.Typed_zk_rollup {|
      Script_typed_ir.typed_contract.Typed_zk_rollup.arg_ty := tya ;
      Script_typed_ir.typed_contract.Typed_zk_rollup.zk_rollup := zk_rollup
    |})
  | Sapling_transaction_value s : value Ty.Sapling_transaction s
  | Sapling_transaction_deprecated_value td :
      value Ty.Sapling_transaction_deprecated td
  | Sapling_state_value s : value Ty.Sapling_state s
  | Operation_value s : value Ty.Operation s
  | Chain_id_value s : value Ty.Chain_id s
  | Never_value n : value Ty.Never n
  | Bls12_381_g1_value v : value Ty.Bls12_381_g1 v
  | Bls12_381_g2_value v : value Ty.Bls12_381_g2 v
  | Bls12_381_fr_value v : value Ty.Bls12_381_fr v
  | Ticket_value a ticketer amount (contents : Ty.to_Set a) :
    value a contents
    Ticket_amount.Valid.t amount
    value (Ty.Ticket a)
      {|
        Script_typed_ir.ticket.ticketer := ticketer;
        Script_typed_ir.ticket.contents := contents;
        Script_typed_ir.ticket.amount := amount;
      |}
  | Chest_key_value v : value Ty.Chest_key v
  | Chest_value v : value Ty.Chest v

  
Validity predicate for [kdescr]
  with kdescr : Stack_ty.t Stack_ty.t Script_typed_ir.kdescr Prop :=
  | Kdescr loc bef aft instr vbef vaft :
    stack_ty.Valid.t vbef bef
    stack_ty.Valid.t vaft aft
    kinstr vbef vaft instr
    kdescr vbef vaft
      {|
        Script_typed_ir.kdescr.kloc := loc;
        Script_typed_ir.kdescr.kbef := bef;
        Script_typed_ir.kdescr.kaft := aft;
        Script_typed_ir.kdescr.kinstr := instr;
      |}

  
Validity predicate for [lambda]
  with lambda : Stack_ty.t Stack_ty.t Script_typed_ir.lambda Prop :=
  | Lam k_descr node arg ret :
    kdescr [arg] [ret] k_descr
    lambda [arg] [ret] (Script_typed_ir.Lam k_descr node)
  | LamRec k_descr node arg ret :
    kdescr [arg ; Ty.Lambda arg ret] [ret] k_descr
    lambda [arg ; Ty.Lambda arg ret] [ret] (Script_typed_ir.LamRec k_descr node)

  where
  "'Script_Map" :=
    (fun (k : Ty.t)
       (tyk : Script_typed_ir.ty)
       (k_cmp : ty.Comparable.t tyk)
       (k_tyk : ty.Valid.proj_rel k tyk) ⇒
       Map.Make {|
           Compare.COMPARABLE.compare :=
             Script_comparable.compare_comparable tyk; |}).

  Definition Script_Map
    (k : Ty.t)
    (tyk : Script_typed_ir.ty)
    (k_cmp : ty.Comparable.t tyk)
    (k_tyk : ty.Valid.proj_rel k tyk) : Map.S (key := Ty.to_Set k) :=
    'Script_Map k tyk k_cmp k_tyk.

Validity predicate for [typed_contract]
  Inductive typed_contract : Ty.t Script_typed_ir.typed_contract Prop :=
  | Typed_implicit akh : typed_contract Ty.Unit (Script_typed_ir.Typed_implicit akh)
  | Typed_originated t tya hash entry :
    ty.Valid.proj_rel t tya
    typed_contract t (Script_typed_ir.Typed_originated {|
      Script_typed_ir.typed_contract.Typed_originated.arg_ty := tya ;
      Script_typed_ir.typed_contract.Typed_originated.contract_hash := hash ;
      Script_typed_ir.typed_contract.Typed_originated.entrypoint := entry
    |})
  | Typed_tx_rollup t tya tx_rollup :
    ty.Valid.proj_rel (Ty.Pair (Ty.Ticket t) Ty.Tx_rollup_l2_address) tya
    typed_contract
      (Ty.Pair (Ty.Ticket t) Ty.Tx_rollup_l2_address)
      (Script_typed_ir.Typed_tx_rollup {|
       Script_typed_ir.typed_contract.Typed_tx_rollup.arg_ty := tya ;
       Script_typed_ir.typed_contract.Typed_tx_rollup.tx_rollup := tx_rollup
    |})
  | Typed_sc_rollup a tya sc_rollup entrypoint :
    ty.Valid.proj_rel a tya
    typed_contract (Ty.Contract a) (Script_typed_ir.Typed_sc_rollup {|
      Script_typed_ir.typed_contract.Typed_sc_rollup.arg_ty := tya ;
      Script_typed_ir.typed_contract.Typed_sc_rollup.sc_rollup := sc_rollup ;
      Script_typed_ir.typed_contract.Typed_sc_rollup.entrypoint := entrypoint
    |})
  | Typed_zk_rollup a tya zk_rollup :
    ty.Valid.proj_rel a tya
    typed_contract (Ty.Contract a) (Script_typed_ir.Typed_zk_rollup {|
      Script_typed_ir.typed_contract.Typed_zk_rollup.arg_ty := tya ;
      Script_typed_ir.typed_contract.Typed_zk_rollup.zk_rollup := zk_rollup
    |}).

Validity predicate for [continuation]
  Inductive continuation :
    Stack_ty.t Stack_ty.t Script_typed_ir.continuation Prop :=
  | KNil f : continuation f f Script_typed_ir.KNil
  | KCons s t f k c :
    kinstr s t k
    continuation t f c
    continuation s f (Script_typed_ir.KCons k c)
  | KReturn a s f ostack st c (stv : Stack_ty.to_Set s) :
    Option.Forall (stack_ty.Valid.t st) ostack
    continuation (a :: s) f c
    continuation [a] f (Script_typed_ir.KReturn stv ostack c)
  | KMap_head a b aty bty (g : Ty.to_Set a Ty.to_Set b) s f c :
    ty.Valid.proj_rel a aty
    ty.Valid.proj_rel b bty
    continuation (a :: s) f c
    continuation (b :: s) f (Script_typed_ir.KMap_head g c)
  | KUndip b s f bty (bv : Ty.to_Set b) c :
    value b bv
    Option.Forall (ty.Valid.proj_rel b) bty
    continuation (b :: s) f c
    continuation s f (Script_typed_ir.KUndip bv bty c)
  | KLoop_in s f k c :
    kinstr s (Ty.Bool :: s) k
    continuation s f c
    continuation (Ty.Bool :: s) f (Script_typed_ir.KLoop_in k c)
  | KLoop_in_left a b s f k c :
    kinstr (a :: s) (Ty.Union a b :: s) k
    continuation (b :: s) f c
    continuation
      (Ty.Union a b :: s) f
      (Script_typed_ir.KLoop_in_left k c)
  | KIter a aty s f k c (l : list (Ty.to_Set a)) :
    List.Forall (value a) l
    kinstr (a :: s) s k
    Option.Forall (ty.Valid.proj_rel a) aty
    continuation s f c
    continuation s f (Script_typed_ir.KIter k aty l c)
  | KList_enter_body
      a b s f blty
      (la : list (Ty.to_Set a))
      (lb : Script_list.t (Ty.to_Set b))
      k c (i : int) :
    kinstr (a :: s) (b :: s) k
    List.Forall (value a) la
    Option.Forall (ty.Valid.proj_rel (Ty.List b)) blty
    continuation (Ty.List b :: s) f c
    continuation s f (Script_typed_ir.KList_enter_body k la lb blty i c)
  | KList_exit_body
      a b s f blty
      (la : list (Ty.to_Set a))
      (lb : Script_list.t (Ty.to_Set b))
      k c (i : int) :
    kinstr (a :: s) (b :: s) k
    List.Forall (value a) la
    Option.Forall (ty.Valid.proj_rel (Ty.List b)) blty
    continuation (Ty.List b :: s) f c
    continuation s f (Script_typed_ir.KList_exit_body k la lb blty i c)
  | KMap_enter_body
      a b d s f k c
      (lab : list (Ty.to_Set a × Ty.to_Set b))
      (mad : Script_typed_ir.map (Ty.to_Set a) (Ty.to_Set d))
      madt :
    kinstr (Ty.Pair a b :: s) (d :: s) k
    List.Forall (value (Ty.Pair a b)) lab
    Option.Forall (ty.Valid.proj_rel (Ty.Map a d)) madt
    continuation (Ty.Map a d :: s) f c
    continuation (d :: s) f (Script_typed_ir.KMap_enter_body k lab mad madt c)
  | KMap_exit_body
      a b d s f k c
      (lab : list (Ty.to_Set a × Ty.to_Set b))
      (mad : Script_typed_ir.map (Ty.to_Set a) (Ty.to_Set d))
      (va : Ty.to_Set a)
      madt :
    kinstr (Ty.Pair a b :: s) (d :: s) k
    List.Forall (value (Ty.Pair a b)) lab
    value a va
    Option.Forall (ty.Valid.proj_rel (Ty.Map a d)) madt
    continuation (Ty.Map a d :: s) f c
    continuation (d :: s) f (Script_typed_ir.KMap_exit_body k lab mad va madt c)
  | KView_exit s f (cns : step_constants) c :
    continuation s f c
    continuation s f (Script_typed_ir.KView_exit cns c)
  (* We choose to ignore the [KLog] function. *).
End Valid.

Module ticket.
  Module Valid.
Validity predicate for [Script_typed_ir.ticket], which actually uses a clone of [value.Ticket_value] above.
    Inductive t : (a : Ty.t), Script_typed_ir.ticket (Ty.to_Set a) Prop :=
      | Ticket a ticketer amount (contents : Ty.to_Set a) :
        Valid.value a contents Ticket_amount.Valid.t amount
        t a
          {|
            Script_typed_ir.ticket.ticketer := ticketer;
            Script_typed_ir.ticket.contents := contents;
            Script_typed_ir.ticket.amount := amount;
          |}.
  End Valid.
End ticket.

Module Script_signature.
  Import Proto_alpha.Script_typed_ir.Script_signature.

  Lemma make_get (s : t) : make (get s) = s.
  Proof.
    now destruct s.
  Qed.

  Lemma get_make (s : Signature.t) : get (make s) = s.
  Proof.
    reflexivity.
  Qed.

  Lemma encoding_is_valid : Data_encoding.Valid.t (fun _True) encoding.
  Proof.
    Data_encoding.Valid.data_encoding_auto.
  Qed.
  #[global] Hint Resolve encoding_is_valid : Data_encoding_db.

  Definition canonize (s : t) : t :=
    make (Signature.canonize (get s)).

  Lemma compare_is_valid : Compare.Valid.t (fun _True) canonize compare.
  Proof.
    apply (Compare.equality (Compare.projection get Signature.compare));
      [sauto lq: on|].
    eapply Compare.implies.
    { eapply Compare.projection_is_valid.
      apply Signature.compare_is_valid.
    }
    all: unfold canonize, get; hauto l: on.
  Qed.
End Script_signature.

Module tx_rollup_l2_address.
  Module Valid.
Validity predicate for [tx_rollup_l2_address]. Note that it clones [value.Tx_rollup_l2_address_value].
    Definition t (x : Script_typed_ir.tx_rollup_l2_address) : Prop :=
      Indexable.Value.Valid.t x.
  End Valid.
End tx_rollup_l2_address.

Module Script_chain_id.
  Import Proto_alpha.Script_typed_ir.Script_chain_id.

  Lemma compare_is_valid : Compare.Valid.t (fun _True) id compare.
  Proof.
    apply (Compare.equality (
      let proj '(Chain_id_tag x) := x in
      Compare.projection proj Chain_id.compare
    )); [sauto q: on|].
    eapply Compare.implies.
    { eapply Compare.projection_is_valid.
      apply Chain_id.compare_is_valid.
    }
    all: sauto q: on.
  Qed.

  Lemma encoding_is_valid : Data_encoding.Valid.t (fun _True) encoding.
  Proof.
    Data_encoding.Valid.data_encoding_auto.
  Qed.
  #[global] Hint Resolve encoding_is_valid : Data_encoding_db.
End Script_chain_id.

Module Script_timelock.
  Import Proto_alpha.Script_typed_ir.Script_timelock.

  Lemma chest_key_encoding_is_valid : Data_encoding.Valid.t (fun _True) chest_key_encoding.
  Proof.
    Data_encoding.Valid.data_encoding_auto.
  Qed.
  #[global] Hint Resolve chest_key_encoding_is_valid : Data_encoding_db.

  Lemma chest_encoding_is_valid : Data_encoding.Valid.t (fun _True) chest_encoding.
  Proof.
    Data_encoding.Valid.data_encoding_auto.
  Qed.
  #[global] Hint Resolve chest_encoding_is_valid : Data_encoding_db.

End Script_timelock.

Module step_constants.
  Module Valid.
The validity of the step_constants
    Record t (sc : step_constants) : Prop := {
      amount : Tez_repr.Valid.t sc.(step_constants.amount);
      balance : Tez_repr.Valid.t sc.(step_constants.balance);
      level : Script_int.n_num.Valid.t sc.(step_constants.level);
    }.
  End Valid.
End step_constants.

Module Type_size.
  Module Valid.
Validity predicate for the type [Type_size.t].
    Definition t (x : Script_typed_ir.Type_size.t) : Prop :=
      0 x Constants_repr.michelson_maximum_type_size.
    #[global] Hint Unfold
      t
      Constants_repr.michelson_maximum_type_size
      : tezos_z.
  End Valid.

The function [of_int] is valid.
  Lemma of_int_is_valid loc_value size_value :
    Pervasives.Int.Valid.non_negative size_value
    letP? size := Type_size.of_int loc_value size_value in
    Valid.t size.
  Proof.
    intros H_size_value.
    unfold Type_size.of_int.
    destruct (_ i _) eqn:?; simpl; [|easy].
    lia.
  Qed.

The function [compound1] is valid.
  Lemma compound1_is_valid loc_value size_value :
    Valid.t size_value
    letP? size := Type_size.compound1 loc_value size_value in
    Valid.t size.
  Proof.
    intros H_size_value.
    apply of_int_is_valid.
    lia.
  Qed.

The function [compound2] is valid.
  Lemma compound2_is_valid loc_value size1 size2 :
    Valid.t size1
    Valid.t size2
    letP? size := Type_size.compound2 loc_value size1 size2 in
    Valid.t size.
  Proof.
    intros Hsize1 Hsize2.
    apply of_int_is_valid.
    lia.
  Qed.
End Type_size.

Module ty_metadata.
  Module Valid.
    Import Proto_alpha.Script_typed_ir.ty_metadata.

Validity predicate for the type [ty_metadata].
    Record t (x : Script_typed_ir.ty_metadata) : Prop := {
      size : Type_size.Valid.t x.(size);
    }.
  End Valid.
End ty_metadata.

Module ex_ty.
  Module Valid.
Validity predicate for the type [ex_ty], which: in coq-of-ocaml, is an alias of [ty]. in OCaml, is specified with: [type ex_ty = Ex_ty : ('a, _) ty -> ex_ty]
    Definition t ex_ty :=
      let 'Ex_ty ty := ex_ty in ty.Valid.t ty.
  End Valid.
End ex_ty.

The value [meta_basic] is valid.
The function [ticket_t] is valid