open Prims
let dbg : Prims.bool FStarC_Effect.ref= FStarC_Debug.get_toggle "ED"
let dbg_LayeredEffectsTc : Prims.bool FStarC_Effect.ref=
  FStarC_Debug.get_toggle "LayeredEffectsTc"
let check_and_gen (env : FStarC_TypeChecker_Env.env)
  (eff_name : Prims.string) (comb : Prims.string) (n : Prims.int)
  (us_t : (FStarC_Syntax_Syntax.univ_names * FStarC_Syntax_Syntax.term)) :
  (FStarC_Syntax_Syntax.univ_names * FStarC_Syntax_Syntax.term *
    FStarC_Syntax_Syntax.typ)=
  let uu___ = us_t in
  match uu___ with
  | (us, t) ->
      let uu___1 =
        let uu___2 =
          let uu___3 =
            let uu___4 =
              FStarC_Class_Show.show
                (FStarC_Class_Show.show_tuple2
                   (FStarC_Class_Show.show_list FStarC_Ident.showable_ident)
                   FStarC_Syntax_Print.showable_term) (us, t) in
            Prims.strcat " = " uu___4 in
          Prims.strcat comb uu___3 in
        Prims.strcat "While checking combinator " uu___2 in
      FStarC_Errors.with_ctx uu___1
        (fun uu___2 ->
           let uu___3 = FStarC_Syntax_Subst.open_univ_vars us t in
           match uu___3 with
           | (us1, t1) ->
               let uu___4 =
                 let env1 = FStarC_TypeChecker_Env.push_univ_vars env us1 in
                 let uu___5 =
                   FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term env1 t1 in
                 match uu___5 with
                 | (t2, lc, g) ->
                     (FStarC_TypeChecker_Rel.force_trivial_guard env1 g;
                      (t2, (lc.FStarC_TypeChecker_Common.res_typ))) in
               (match uu___4 with
                | (t2, ty) ->
                    let uu___5 =
                      FStarC_TypeChecker_Generalize.generalize_universes env
                        t2 in
                    (match uu___5 with
                     | (g_us, t3) ->
                         let ty1 =
                           FStarC_Syntax_Subst.close_univ_vars g_us ty in
                         (if (FStarC_List.length g_us) <> n
                          then
                            (let error =
                               let uu___6 =
                                 FStarC_Class_Show.show
                                   FStarC_Class_Show.showable_int n in
                               let uu___7 =
                                 FStarC_Class_Show.show
                                   FStarC_Class_Show.showable_nat
                                   (FStarC_List.length g_us) in
                               let uu___8 =
                                 FStarC_Syntax_Print.tscheme_to_string
                                   (g_us, t3) in
                               FStarC_Format.fmt5
                                 "Expected %s:%s to be universe-polymorphic in %s universes, but found %s (tscheme: %s)"
                                 eff_name comb uu___6 uu___7 uu___8 in
                             FStarC_Errors.raise_error
                               (FStarC_Syntax_Syntax.has_range_syntax ()) t3
                               FStarC_Errors_Codes.Fatal_MismatchUniversePolymorphic
                               ()
                               (Obj.magic
                                  FStarC_Errors_Msg.is_error_message_string)
                               (Obj.magic error);
                             (match us1 with
                              | [] -> ()
                              | uu___7 ->
                                  let uu___8 =
                                    if
                                      (FStarC_List.length us1) =
                                        (FStarC_List.length g_us)
                                    then
                                      FStarC_List.forall2
                                        (fun u1 u2 ->
                                           (FStarC_Syntax_Syntax.order_univ_name
                                              u1 u2)
                                             = Prims.int_zero) us1 g_us
                                    else false in
                                  if uu___8
                                  then ()
                                  else
                                    (let uu___9 =
                                       let uu___10 =
                                         FStarC_Class_Show.show
                                           (FStarC_Class_Show.show_list
                                              FStarC_Ident.showable_ident)
                                           us1 in
                                       let uu___11 =
                                         FStarC_Class_Show.show
                                           (FStarC_Class_Show.show_list
                                              FStarC_Ident.showable_ident)
                                           g_us in
                                       FStarC_Format.fmt4
                                         "Expected and generalized universes in the declaration for %s:%s are different, input: %s, but after gen: %s"
                                         eff_name comb uu___10 uu___11 in
                                     FStarC_Errors.raise_error
                                       (FStarC_Syntax_Syntax.has_range_syntax
                                          ()) t3
                                       FStarC_Errors_Codes.Fatal_UnexpectedNumberOfUniverse
                                       ()
                                       (Obj.magic
                                          FStarC_Errors_Msg.is_error_message_string)
                                       (Obj.magic uu___9))))
                          else ();
                          (g_us, t3, ty1)))))
let pure_wp_uvar (env : FStarC_TypeChecker_Env.env)
  (t : FStarC_Syntax_Syntax.typ) (reason : Prims.string)
  (r : FStarC_Range_Type.t) :
  (FStarC_Syntax_Syntax.term * FStarC_TypeChecker_Common.guard_t)=
  let pure_wp_t =
    let pure_wp_ts =
      let uu___ =
        FStarC_TypeChecker_Env.lookup_definition
          [FStarC_TypeChecker_Env.NoDelta] env
          FStarC_Parser_Const.pure_wp_lid in
      FStarC_Option.must uu___ in
    let uu___ = FStarC_TypeChecker_Env.inst_tscheme pure_wp_ts in
    match uu___ with
    | (uu___1, pure_wp_t1) ->
        FStarC_Syntax_Syntax.mk_Tm_app pure_wp_t1
          [FStarC_Syntax_Syntax.as_arg t] r in
  let uu___ =
    FStarC_TypeChecker_Env.new_implicit_var_aux reason r env pure_wp_t
      FStarC_Syntax_Syntax.Strict FStar_Pervasives_Native.None false in
  match uu___ with
  | (pure_wp_uvar1, uu___1, guard_wp) -> (pure_wp_uvar1, guard_wp)
let op_let_Question (f : 'a FStar_Pervasives_Native.option)
  (g : 'a -> 'b FStar_Pervasives_Native.option) :
  'b FStar_Pervasives_Native.option=
  match f with
  | FStar_Pervasives_Native.None -> FStar_Pervasives_Native.None
  | FStar_Pervasives_Native.Some x -> g x
let mteq (env : FStarC_TypeChecker_Env.env) (t1 : FStarC_Syntax_Syntax.typ)
  (t2 : FStarC_Syntax_Syntax.typ) : Prims.bool=
  try
    (fun uu___ ->
       match () with | () -> FStarC_TypeChecker_Rel.teq_nosmt_force env t1 t2)
      ()
  with | uu___ -> false
let eq_binders (env : FStarC_TypeChecker_Env.env)
  (bs1 : FStarC_Syntax_Syntax.binders) (bs2 : FStarC_Syntax_Syntax.binders) :
  FStarC_Syntax_Syntax.indexed_effect_binder_kind Prims.list
    FStar_Pervasives_Native.option=
  let uu___ =
    let uu___1 =
      FStarC_List.fold_left2
        (fun uu___2 b1 b2 ->
           match uu___2 with
           | (b, ss) ->
               let uu___3 =
                 if b
                 then
                   let uu___4 =
                     FStarC_Syntax_Subst.subst ss
                       (b1.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort in
                   mteq env uu___4
                     (b2.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                 else false in
               let uu___4 =
                 let uu___5 =
                   let uu___6 =
                     let uu___7 =
                       let uu___8 =
                         FStarC_Syntax_Syntax.bv_to_name
                           b2.FStarC_Syntax_Syntax.binder_bv in
                       ((b1.FStarC_Syntax_Syntax.binder_bv), uu___8) in
                     FStarC_Syntax_Syntax.NT uu___7 in
                   [uu___6] in
                 FStarC_List.op_At ss uu___5 in
               (uu___3, uu___4)) (true, []) bs1 bs2 in
    FStar_Pervasives_Native.fst uu___1 in
  if uu___
  then
    let uu___1 =
      FStarC_List.map
        (fun uu___2 -> FStarC_Syntax_Syntax.Substitutive_binder) bs1 in
    FStar_Pervasives_Native.Some uu___1
  else FStar_Pervasives_Native.None
let log_ad_hoc_combinator_warning (comb_name : Prims.string)
  (r : FStarC_Range_Type.t) : unit=
  FStarC_Errors.log_issue FStarC_Class_HasRange.hasRange_range r
    FStarC_Errors_Codes.Warning_Adhoc_IndexedEffect_Combinator ()
    (Obj.magic FStarC_Errors_Msg.is_error_message_list_doc)
    (Obj.magic
       [FStarC_Errors_Msg.text
          (FStarC_Format.fmt1
             "Combinator %s is not a substitutive indexed effect combinator, it is better to make it one if possible for better performance and ease of use"
             comb_name)])
let bind_combinator_kind (env : FStarC_TypeChecker_Env.env)
  (m_eff_name : FStarC_Ident.lident) (n_eff_name : FStarC_Ident.lident)
  (p_eff_name : FStarC_Ident.lident)
  (m_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (n_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (p_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (m_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (n_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (p_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (bind_us : FStarC_Syntax_Syntax.univ_names) (k : FStarC_Syntax_Syntax.typ)
  (num_effect_params : Prims.int) (has_range_binders : Prims.bool) :
  FStarC_Syntax_Syntax.indexed_effect_binder_kind Prims.list
    FStar_Pervasives_Native.option=
  let debug s =
    let uu___ =
      let uu___1 = FStarC_Debug.medium () in
      if uu___1 then true else FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
    if uu___ then FStarC_Format.print1 "%s\n" s else () in
  (let uu___1 =
     let uu___2 =
       FStarC_Class_Show.show FStarC_Class_Show.showable_int
         num_effect_params in
     FStarC_Format.fmt1
       "Checking bind combinator kind with %s effect parameters" uu___2 in
   debug uu___1);
  (let uu___1 = bind_us in
   match uu___1 with
   | u_a::u_b::[] ->
       let uu___2 =
         let uu___3 = FStarC_Syntax_Util.arrow_formals k in
         FStar_Pervasives_Native.fst uu___3 in
       (match uu___2 with
        | a_b::b_b::rest_bs ->
            let uu___3 =
              if num_effect_params = Prims.int_zero
              then FStar_Pervasives_Native.Some ([], [], rest_bs)
              else
                (let uu___4 =
                   FStarC_TypeChecker_Env.inst_tscheme_with m_sig_ts
                     [FStarC_Syntax_Syntax.U_name u_a] in
                 match uu___4 with
                 | (uu___5, sig1) ->
                     let sig_bs =
                       let uu___6 =
                         let uu___7 = FStarC_Syntax_Util.arrow_formals sig1 in
                         FStar_Pervasives_Native.fst uu___7 in
                       FStarC_List.tl uu___6 in
                     op_let_Question
                       (if (FStarC_List.length sig_bs) < num_effect_params
                        then FStar_Pervasives_Native.None
                        else
                          FStar_Pervasives_Native.Some
                            (FStar_Pervasives_Native.fst
                               (FStarC_List.splitAt num_effect_params sig_bs)))
                       (fun sig_eff_params_bs ->
                          op_let_Question
                            (if
                               (FStarC_List.length rest_bs) <
                                 num_effect_params
                             then FStar_Pervasives_Native.None
                             else
                               FStar_Pervasives_Native.Some
                                 (FStarC_List.splitAt num_effect_params
                                    rest_bs))
                            (fun uu___6 ->
                               match uu___6 with
                               | (eff_params_bs, rest_bs1) ->
                                   let uu___7 =
                                     eq_binders env sig_eff_params_bs
                                       eff_params_bs in
                                   op_let_Question uu___7
                                     (fun eff_params_bs_kinds ->
                                        FStar_Pervasives_Native.Some
                                          (eff_params_bs,
                                            eff_params_bs_kinds, rest_bs1))))) in
            op_let_Question uu___3
              (fun uu___4 ->
                 match uu___4 with
                 | (eff_params_bs, eff_params_bs_kinds, rest_bs1) ->
                     let uu___5 =
                       let f_sig_bs =
                         let uu___6 =
                           FStarC_TypeChecker_Env.inst_tscheme_with m_sig_ts
                             [FStarC_Syntax_Syntax.U_name u_a] in
                         match uu___6 with
                         | (uu___7, sig1) ->
                             let uu___8 =
                               let uu___9 =
                                 FStarC_Syntax_Util.arrow_formals sig1 in
                               FStar_Pervasives_Native.fst uu___9 in
                             (match uu___8 with
                              | a::bs ->
                                  let uu___9 =
                                    FStarC_List.splitAt num_effect_params bs in
                                  (match uu___9 with
                                   | (sig_bs, bs1) ->
                                       let ss =
                                         let uu___10 =
                                           let uu___11 =
                                             let uu___12 =
                                               let uu___13 =
                                                 FStarC_Syntax_Syntax.bv_to_name
                                                   a_b.FStarC_Syntax_Syntax.binder_bv in
                                               ((a.FStarC_Syntax_Syntax.binder_bv),
                                                 uu___13) in
                                             FStarC_Syntax_Syntax.NT uu___12 in
                                           [uu___11] in
                                         FStarC_List.fold_left2
                                           (fun ss1 sig_b b ->
                                              let uu___11 =
                                                let uu___12 =
                                                  let uu___13 =
                                                    let uu___14 =
                                                      FStarC_Syntax_Syntax.bv_to_name
                                                        b.FStarC_Syntax_Syntax.binder_bv in
                                                    ((sig_b.FStarC_Syntax_Syntax.binder_bv),
                                                      uu___14) in
                                                  FStarC_Syntax_Syntax.NT
                                                    uu___13 in
                                                [uu___12] in
                                              FStarC_List.op_At ss1 uu___11)
                                           uu___10 sig_bs eff_params_bs in
                                       FStarC_Syntax_Subst.subst_binders ss
                                         bs1)) in
                       op_let_Question
                         (if
                            (FStarC_List.length rest_bs1) <
                              (FStarC_List.length f_sig_bs)
                          then FStar_Pervasives_Native.None
                          else
                            FStar_Pervasives_Native.Some
                              (FStarC_List.splitAt
                                 (FStarC_List.length f_sig_bs) rest_bs1))
                         (fun uu___6 ->
                            match uu___6 with
                            | (f_bs, rest_bs2) ->
                                let uu___7 = eq_binders env f_sig_bs f_bs in
                                op_let_Question uu___7
                                  (fun f_bs_kinds ->
                                     FStar_Pervasives_Native.Some
                                       (f_bs, f_bs_kinds, rest_bs2))) in
                     op_let_Question uu___5
                       (fun uu___6 ->
                          match uu___6 with
                          | (f_bs, f_bs_kinds, rest_bs2) ->
                              let uu___7 =
                                let g_sig_bs =
                                  let uu___8 =
                                    FStarC_TypeChecker_Env.inst_tscheme_with
                                      n_sig_ts
                                      [FStarC_Syntax_Syntax.U_name u_b] in
                                  match uu___8 with
                                  | (uu___9, sig1) ->
                                      let uu___10 =
                                        let uu___11 =
                                          FStarC_Syntax_Util.arrow_formals
                                            sig1 in
                                        FStar_Pervasives_Native.fst uu___11 in
                                      (match uu___10 with
                                       | b::bs ->
                                           let uu___11 =
                                             FStarC_List.splitAt
                                               num_effect_params bs in
                                           (match uu___11 with
                                            | (sig_bs, bs1) ->
                                                let ss =
                                                  let uu___12 =
                                                    let uu___13 =
                                                      let uu___14 =
                                                        let uu___15 =
                                                          FStarC_Syntax_Syntax.bv_to_name
                                                            b_b.FStarC_Syntax_Syntax.binder_bv in
                                                        ((b.FStarC_Syntax_Syntax.binder_bv),
                                                          uu___15) in
                                                      FStarC_Syntax_Syntax.NT
                                                        uu___14 in
                                                    [uu___13] in
                                                  FStarC_List.fold_left2
                                                    (fun ss1 sig_b b1 ->
                                                       let uu___13 =
                                                         let uu___14 =
                                                           let uu___15 =
                                                             let uu___16 =
                                                               FStarC_Syntax_Syntax.bv_to_name
                                                                 b1.FStarC_Syntax_Syntax.binder_bv in
                                                             ((sig_b.FStarC_Syntax_Syntax.binder_bv),
                                                               uu___16) in
                                                           FStarC_Syntax_Syntax.NT
                                                             uu___15 in
                                                         [uu___14] in
                                                       FStarC_List.op_At ss1
                                                         uu___13) uu___12
                                                    sig_bs eff_params_bs in
                                                FStarC_Syntax_Subst.subst_binders
                                                  ss bs1)) in
                                op_let_Question
                                  (if
                                     (FStarC_List.length rest_bs2) <
                                       (FStarC_List.length g_sig_bs)
                                   then FStar_Pervasives_Native.None
                                   else
                                     FStar_Pervasives_Native.Some
                                       (FStarC_List.splitAt
                                          (FStarC_List.length g_sig_bs)
                                          rest_bs2))
                                  (fun uu___8 ->
                                     match uu___8 with
                                     | (g_bs, rest_bs3) ->
                                         let uu___9 =
                                           let uu___10 =
                                             FStarC_List.fold_left2
                                               (fun uu___11 g_sig_b g_b ->
                                                  match uu___11 with
                                                  | (l, ss) ->
                                                      let g_sig_b_sort =
                                                        FStarC_Syntax_Subst.subst
                                                          ss
                                                          (g_sig_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort in
                                                      let g_sig_b_arrow_t =
                                                        let x_bv =
                                                          let uu___12 =
                                                            FStarC_Syntax_Syntax.bv_to_name
                                                              a_b.FStarC_Syntax_Syntax.binder_bv in
                                                          FStarC_Syntax_Syntax.gen_bv
                                                            "x"
                                                            FStar_Pervasives_Native.None
                                                            uu___12 in
                                                        let ss1 =
                                                          let uu___12 =
                                                            FStarC_List.map
                                                              (fun uu___13 ->
                                                                 match uu___13
                                                                 with
                                                                 | (bv, k1)
                                                                    ->
                                                                    if
                                                                    k1 =
                                                                    FStarC_Syntax_Syntax.Substitutive_binder
                                                                    then
                                                                    let uu___14
                                                                    =
                                                                    let uu___15
                                                                    =
                                                                    let uu___16
                                                                    =
                                                                    let uu___17
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    bv in
                                                                    let uu___18
                                                                    =
                                                                    let uu___19
                                                                    =
                                                                    let uu___20
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    x_bv in
                                                                    FStarC_Syntax_Syntax.as_arg
                                                                    uu___20 in
                                                                    [uu___19] in
                                                                    FStarC_Syntax_Syntax.mk_Tm_app
                                                                    uu___17
                                                                    uu___18
                                                                    FStarC_Range_Type.dummyRange in
                                                                    (bv,
                                                                    uu___16) in
                                                                    FStarC_Syntax_Syntax.NT
                                                                    uu___15 in
                                                                    [uu___14]
                                                                    else [])
                                                              l in
                                                          FStarC_List.flatten
                                                            uu___12 in
                                                        let g_sig_b_sort1 =
                                                          FStarC_Syntax_Subst.subst
                                                            ss1 g_sig_b_sort in
                                                        let uu___12 =
                                                          FStarC_Syntax_Syntax.mk_Total
                                                            g_sig_b_sort1 in
                                                        FStarC_Syntax_Util.arrow
                                                          [FStarC_Syntax_Syntax.mk_binder
                                                             x_bv] uu___12 in
                                                      let g_b_kind =
                                                        let uu___12 =
                                                          let uu___13 =
                                                            FStarC_TypeChecker_TermEqAndSimplify.eq_tm
                                                              env
                                                              g_sig_b_arrow_t
                                                              (g_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort in
                                                          uu___13 =
                                                            FStarC_TypeChecker_TermEqAndSimplify.Equal in
                                                        if uu___12
                                                        then
                                                          FStarC_Syntax_Syntax.Substitutive_binder
                                                        else
                                                          (let uu___13 =
                                                             let uu___14 =
                                                               FStarC_TypeChecker_TermEqAndSimplify.eq_tm
                                                                 env
                                                                 g_sig_b_sort
                                                                 (g_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort in
                                                             uu___14 =
                                                               FStarC_TypeChecker_TermEqAndSimplify.Equal in
                                                           if uu___13
                                                           then
                                                             FStarC_Syntax_Syntax.BindCont_no_abstraction_binder
                                                           else
                                                             FStarC_Syntax_Syntax.Ad_hoc_binder) in
                                                      let ss1 =
                                                        let uu___12 =
                                                          let uu___13 =
                                                            let uu___14 =
                                                              let uu___15 =
                                                                FStarC_Syntax_Syntax.bv_to_name
                                                                  g_b.FStarC_Syntax_Syntax.binder_bv in
                                                              ((g_sig_b.FStarC_Syntax_Syntax.binder_bv),
                                                                uu___15) in
                                                            FStarC_Syntax_Syntax.NT
                                                              uu___14 in
                                                          [uu___13] in
                                                        FStarC_List.op_At ss
                                                          uu___12 in
                                                      ((FStarC_List.op_At l
                                                          [((g_b.FStarC_Syntax_Syntax.binder_bv),
                                                             g_b_kind)]),
                                                        ss1)) ([], [])
                                               g_sig_bs g_bs in
                                           match uu___10 with
                                           | (g_bs_kinds, uu___11) ->
                                               let g_bs_kinds1 =
                                                 FStarC_List.map
                                                   FStar_Pervasives_Native.snd
                                                   g_bs_kinds in
                                               if
                                                 FStarC_List.contains
                                                   FStarC_Syntax_Syntax.Ad_hoc_binder
                                                   g_bs_kinds1
                                               then
                                                 FStar_Pervasives_Native.None
                                               else
                                                 FStar_Pervasives_Native.Some
                                                   g_bs_kinds1 in
                                         op_let_Question uu___9
                                           (fun g_bs_kinds ->
                                              FStar_Pervasives_Native.Some
                                                (g_bs, g_bs_kinds, rest_bs3))) in
                              op_let_Question uu___7
                                (fun uu___8 ->
                                   match uu___8 with
                                   | (g_bs, g_bs_kinds, rest_bs3) ->
                                       let uu___9 =
                                         if has_range_binders
                                         then
                                           FStarC_List.splitAt
                                             (Prims.of_int 2) rest_bs3
                                         else ([], rest_bs3) in
                                       (match uu___9 with
                                        | (range_bs, rest_bs4) ->
                                            let uu___10 = uu___9 in
                                            op_let_Question
                                              (if
                                                 (FStarC_List.length rest_bs4)
                                                   >= (Prims.of_int 2)
                                               then
                                                 let uu___11 =
                                                   FStarC_List.splitAt
                                                     ((FStarC_List.length
                                                         rest_bs4)
                                                        - (Prims.of_int 2))
                                                     rest_bs4 in
                                                 match uu___11 with
                                                 | (rest_bs5, f_b::g_b::[])
                                                     ->
                                                     FStar_Pervasives_Native.Some
                                                       (rest_bs5, f_b, g_b)
                                               else
                                                 FStar_Pervasives_Native.None)
                                              (fun uu___11 ->
                                                 match uu___11 with
                                                 | (rest_bs5, f_b, g_b) ->
                                                     let uu___12 =
                                                       let repr_app_bs =
                                                         FStarC_List.op_At
                                                           eff_params_bs f_bs in
                                                       let expected_f_b_sort
                                                         =
                                                         match m_repr_ts with
                                                         | FStar_Pervasives_Native.Some
                                                             repr_ts ->
                                                             let uu___13 =
                                                               FStarC_TypeChecker_Env.inst_tscheme_with
                                                                 repr_ts
                                                                 [FStarC_Syntax_Syntax.U_name
                                                                    u_a] in
                                                             (match uu___13
                                                              with
                                                              | (uu___14, t)
                                                                  ->
                                                                  let uu___15
                                                                    =
                                                                    let uu___16
                                                                    =
                                                                    let uu___17
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    a_b.FStarC_Syntax_Syntax.binder_bv in
                                                                    FStarC_Syntax_Syntax.as_arg
                                                                    uu___17 in
                                                                    let uu___17
                                                                    =
                                                                    FStarC_List.map
                                                                    (fun
                                                                    uu___18
                                                                    ->
                                                                    match uu___18
                                                                    with
                                                                    | 
                                                                    {
                                                                    FStarC_Syntax_Syntax.binder_bv
                                                                    = b;
                                                                    FStarC_Syntax_Syntax.binder_qual
                                                                    = uu___19;
                                                                    FStarC_Syntax_Syntax.binder_positivity
                                                                    = uu___20;
                                                                    FStarC_Syntax_Syntax.binder_attrs
                                                                    = uu___21;_}
                                                                    ->
                                                                    let uu___22
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b in
                                                                    FStarC_Syntax_Syntax.as_arg
                                                                    uu___22)
                                                                    repr_app_bs in
                                                                    uu___16
                                                                    ::
                                                                    uu___17 in
                                                                  FStarC_Syntax_Syntax.mk_Tm_app
                                                                    t uu___15
                                                                    FStarC_Range_Type.dummyRange)
                                                         | FStar_Pervasives_Native.None
                                                             ->
                                                             let uu___13 =
                                                               let uu___14 =
                                                                 FStarC_Syntax_Syntax.null_binder
                                                                   FStarC_Syntax_Syntax.t_unit in
                                                               [uu___14] in
                                                             let uu___14 =
                                                               let uu___15 =
                                                                 let uu___16
                                                                   =
                                                                   FStarC_Syntax_Syntax.bv_to_name
                                                                    a_b.FStarC_Syntax_Syntax.binder_bv in
                                                                 let uu___17
                                                                   =
                                                                   FStarC_List.map
                                                                    (fun b ->
                                                                    let uu___18
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b.FStarC_Syntax_Syntax.binder_bv in
                                                                    FStarC_Syntax_Syntax.as_arg
                                                                    uu___18)
                                                                    repr_app_bs in
                                                                 {
                                                                   FStarC_Syntax_Syntax.comp_univs
                                                                    =
                                                                    [
                                                                    FStarC_Syntax_Syntax.U_name
                                                                    u_a];
                                                                   FStarC_Syntax_Syntax.effect_name
                                                                    =
                                                                    m_eff_name;
                                                                   FStarC_Syntax_Syntax.result_typ
                                                                    = uu___16;
                                                                   FStarC_Syntax_Syntax.effect_args
                                                                    = uu___17;
                                                                   FStarC_Syntax_Syntax.flags
                                                                    = []
                                                                 } in
                                                               FStarC_Syntax_Syntax.mk_Comp
                                                                 uu___15 in
                                                             FStarC_Syntax_Util.arrow
                                                               uu___13
                                                               uu___14 in
                                                       let uu___13 =
                                                         let uu___14 =
                                                           FStarC_TypeChecker_TermEqAndSimplify.eq_tm
                                                             env
                                                             (f_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                                                             expected_f_b_sort in
                                                         uu___14 =
                                                           FStarC_TypeChecker_TermEqAndSimplify.Equal in
                                                       if uu___13
                                                       then
                                                         FStar_Pervasives_Native.Some
                                                           ()
                                                       else
                                                         FStar_Pervasives_Native.None in
                                                     op_let_Question uu___12
                                                       (fun _f_b_ok_ ->
                                                          let uu___13 =
                                                            let expected_g_b_sort
                                                              =
                                                              let x_bv =
                                                                let uu___14 =
                                                                  FStarC_Syntax_Syntax.bv_to_name
                                                                    a_b.FStarC_Syntax_Syntax.binder_bv in
                                                                FStarC_Syntax_Syntax.gen_bv
                                                                  "x"
                                                                  FStar_Pervasives_Native.None
                                                                  uu___14 in
                                                              let eff_params_args
                                                                =
                                                                FStarC_List.map
                                                                  (fun
                                                                    uu___14
                                                                    ->
                                                                    match uu___14
                                                                    with
                                                                    | 
                                                                    {
                                                                    FStarC_Syntax_Syntax.binder_bv
                                                                    = b;
                                                                    FStarC_Syntax_Syntax.binder_qual
                                                                    = uu___15;
                                                                    FStarC_Syntax_Syntax.binder_positivity
                                                                    = uu___16;
                                                                    FStarC_Syntax_Syntax.binder_attrs
                                                                    = uu___17;_}
                                                                    ->
                                                                    let uu___18
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b in
                                                                    FStarC_Syntax_Syntax.as_arg
                                                                    uu___18)
                                                                  eff_params_bs in
                                                              let g_bs_args =
                                                                let uu___14 =
                                                                  FStarC_List.map2
                                                                    (
                                                                    fun
                                                                    uu___15
                                                                    kind ->
                                                                    match uu___15
                                                                    with
                                                                    | 
                                                                    {
                                                                    FStarC_Syntax_Syntax.binder_bv
                                                                    = b;
                                                                    FStarC_Syntax_Syntax.binder_qual
                                                                    = uu___16;
                                                                    FStarC_Syntax_Syntax.binder_positivity
                                                                    = uu___17;
                                                                    FStarC_Syntax_Syntax.binder_attrs
                                                                    = uu___18;_}
                                                                    ->
                                                                    if
                                                                    kind =
                                                                    FStarC_Syntax_Syntax.Substitutive_binder
                                                                    then
                                                                    let uu___19
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b in
                                                                    let uu___20
                                                                    =
                                                                    let uu___21
                                                                    =
                                                                    let uu___22
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    x_bv in
                                                                    FStarC_Syntax_Syntax.as_arg
                                                                    uu___22 in
                                                                    [uu___21] in
                                                                    FStarC_Syntax_Syntax.mk_Tm_app
                                                                    uu___19
                                                                    uu___20
                                                                    FStarC_Range_Type.dummyRange
                                                                    else
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b) g_bs
                                                                    g_bs_kinds in
                                                                FStarC_List.map
                                                                  FStarC_Syntax_Syntax.as_arg
                                                                  uu___14 in
                                                              let repr_args =
                                                                FStarC_List.op_At
                                                                  eff_params_args
                                                                  g_bs_args in
                                                              match n_repr_ts
                                                              with
                                                              | FStar_Pervasives_Native.Some
                                                                  repr_ts ->
                                                                  let uu___14
                                                                    =
                                                                    FStarC_TypeChecker_Env.inst_tscheme_with
                                                                    repr_ts
                                                                    [
                                                                    FStarC_Syntax_Syntax.U_name
                                                                    u_b] in
                                                                  (match uu___14
                                                                   with
                                                                   | 
                                                                   (uu___15,
                                                                    repr_hd)
                                                                    ->
                                                                    let repr_app
                                                                    =
                                                                    let uu___16
                                                                    =
                                                                    let uu___17
                                                                    =
                                                                    let uu___18
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b_b.FStarC_Syntax_Syntax.binder_bv in
                                                                    FStarC_Syntax_Syntax.as_arg
                                                                    uu___18 in
                                                                    uu___17
                                                                    ::
                                                                    repr_args in
                                                                    FStarC_Syntax_Syntax.mk_Tm_app
                                                                    repr_hd
                                                                    uu___16
                                                                    FStarC_Range_Type.dummyRange in
                                                                    let uu___16
                                                                    =
                                                                    FStarC_Syntax_Syntax.mk_Total
                                                                    repr_app in
                                                                    FStarC_Syntax_Util.arrow
                                                                    [
                                                                    FStarC_Syntax_Syntax.mk_binder
                                                                    x_bv]
                                                                    uu___16)
                                                              | FStar_Pervasives_Native.None
                                                                  ->
                                                                  let thunk_t
                                                                    =
                                                                    let uu___14
                                                                    =
                                                                    let uu___15
                                                                    =
                                                                    FStarC_Syntax_Syntax.null_binder
                                                                    FStarC_Syntax_Syntax.t_unit in
                                                                    [uu___15] in
                                                                    let uu___15
                                                                    =
                                                                    let uu___16
                                                                    =
                                                                    let uu___17
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b_b.FStarC_Syntax_Syntax.binder_bv in
                                                                    {
                                                                    FStarC_Syntax_Syntax.comp_univs
                                                                    =
                                                                    [
                                                                    FStarC_Syntax_Syntax.U_name
                                                                    u_b];
                                                                    FStarC_Syntax_Syntax.effect_name
                                                                    =
                                                                    n_eff_name;
                                                                    FStarC_Syntax_Syntax.result_typ
                                                                    = uu___17;
                                                                    FStarC_Syntax_Syntax.effect_args
                                                                    =
                                                                    repr_args;
                                                                    FStarC_Syntax_Syntax.flags
                                                                    = []
                                                                    } in
                                                                    FStarC_Syntax_Syntax.mk_Comp
                                                                    uu___16 in
                                                                    FStarC_Syntax_Util.arrow
                                                                    uu___14
                                                                    uu___15 in
                                                                  let uu___14
                                                                    =
                                                                    FStarC_Syntax_Syntax.mk_Total
                                                                    thunk_t in
                                                                  FStarC_Syntax_Util.arrow
                                                                    [
                                                                    FStarC_Syntax_Syntax.mk_binder
                                                                    x_bv]
                                                                    uu___14 in
                                                            let uu___14 =
                                                              let uu___15 =
                                                                FStarC_TypeChecker_TermEqAndSimplify.eq_tm
                                                                  env
                                                                  (g_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                                                                  expected_g_b_sort in
                                                              uu___15 =
                                                                FStarC_TypeChecker_TermEqAndSimplify.Equal in
                                                            if uu___14
                                                            then
                                                              FStar_Pervasives_Native.Some
                                                                ()
                                                            else
                                                              FStar_Pervasives_Native.None in
                                                          op_let_Question
                                                            uu___13
                                                            (fun _g_b_ok ->
                                                               let range_kinds
                                                                 =
                                                                 FStarC_List.map
                                                                   (fun
                                                                    uu___14
                                                                    ->
                                                                    FStarC_Syntax_Syntax.Range_binder)
                                                                   range_bs in
                                                               let rest_kinds
                                                                 =
                                                                 FStarC_List.map
                                                                   (fun
                                                                    uu___14
                                                                    ->
                                                                    FStarC_Syntax_Syntax.Ad_hoc_binder)
                                                                   rest_bs5 in
                                                               FStar_Pervasives_Native.Some
                                                                 (FStarC_List.op_At
                                                                    [FStarC_Syntax_Syntax.Type_binder;
                                                                    FStarC_Syntax_Syntax.Type_binder]
                                                                    (
                                                                    FStarC_List.op_At
                                                                    eff_params_bs_kinds
                                                                    (FStarC_List.op_At
                                                                    f_bs_kinds
                                                                    (FStarC_List.op_At
                                                                    g_bs_kinds
                                                                    (FStarC_List.op_At
                                                                    range_kinds
                                                                    (FStarC_List.op_At
                                                                    rest_kinds
                                                                    [FStarC_Syntax_Syntax.Repr_binder;
                                                                    FStarC_Syntax_Syntax.Repr_binder])))))))))))))))
let validate_indexed_effect_bind_shape (env : FStarC_TypeChecker_Env.env)
  (m_eff_name : FStarC_Ident.lident) (n_eff_name : FStarC_Ident.lident)
  (p_eff_name : FStarC_Ident.lident)
  (m_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (n_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (p_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (m_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (n_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (p_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (bind_us : FStarC_Syntax_Syntax.univ_names)
  (bind_t : FStarC_Syntax_Syntax.typ) (r : FStarC_Range_Type.t)
  (num_effect_params : Prims.int) (has_range_binders : Prims.bool) :
  (FStarC_Syntax_Syntax.typ *
    FStarC_Syntax_Syntax.indexed_effect_combinator_kind)=
  let bind_name =
    FStarC_Format.fmt3 "(%s , %s) |> %s"
      (FStarC_Ident.string_of_lid m_eff_name)
      (FStarC_Ident.string_of_lid n_eff_name)
      (FStarC_Ident.string_of_lid p_eff_name) in
  let uu___ = bind_us in
  match uu___ with
  | u_a::u_b::[] ->
      let a_b =
        let uu___1 =
          let uu___2 =
            FStarC_Syntax_Util.type_with_u (FStarC_Syntax_Syntax.U_name u_a) in
          FStarC_Syntax_Syntax.gen_bv "a" FStar_Pervasives_Native.None uu___2 in
        FStarC_Syntax_Syntax.mk_binder uu___1 in
      let b_b =
        let uu___1 =
          let uu___2 =
            FStarC_Syntax_Util.type_with_u (FStarC_Syntax_Syntax.U_name u_b) in
          FStarC_Syntax_Syntax.gen_bv "b" FStar_Pervasives_Native.None uu___2 in
        FStarC_Syntax_Syntax.mk_binder uu___1 in
      let rest_bs =
        let uu___1 =
          let uu___2 = FStarC_Syntax_Subst.compress bind_t in
          uu___2.FStarC_Syntax_Syntax.n in
        match uu___1 with
        | FStarC_Syntax_Syntax.Tm_arrow
            { FStarC_Syntax_Syntax.bs1 = bs;
              FStarC_Syntax_Syntax.comp = uu___2;_}
            when (FStarC_List.length bs) >= (Prims.of_int 4) ->
            let uu___3 = FStarC_Syntax_Subst.open_binders bs in
            (match uu___3 with
             | { FStarC_Syntax_Syntax.binder_bv = a;
                 FStarC_Syntax_Syntax.binder_qual = uu___4;
                 FStarC_Syntax_Syntax.binder_positivity = uu___5;
                 FStarC_Syntax_Syntax.binder_attrs = uu___6;_}::{
                                                                  FStarC_Syntax_Syntax.binder_bv
                                                                    = b;
                                                                  FStarC_Syntax_Syntax.binder_qual
                                                                    = uu___7;
                                                                  FStarC_Syntax_Syntax.binder_positivity
                                                                    = uu___8;
                                                                  FStarC_Syntax_Syntax.binder_attrs
                                                                    = uu___9;_}::bs1
                 ->
                 let uu___10 =
                   let uu___11 =
                     let uu___12 =
                       let uu___13 =
                         FStarC_Syntax_Syntax.bv_to_name
                           a_b.FStarC_Syntax_Syntax.binder_bv in
                       (a, uu___13) in
                     FStarC_Syntax_Syntax.NT uu___12 in
                   let uu___12 =
                     let uu___13 =
                       let uu___14 =
                         let uu___15 =
                           FStarC_Syntax_Syntax.bv_to_name
                             b_b.FStarC_Syntax_Syntax.binder_bv in
                         (b, uu___15) in
                       FStarC_Syntax_Syntax.NT uu___14 in
                     [uu___13] in
                   uu___11 :: uu___12 in
                 FStarC_Syntax_Subst.subst_binders uu___10
                   (FStar_Pervasives_Native.fst
                      (FStarC_List.splitAt
                         ((FStarC_List.length bs1) - (Prims.of_int 2)) bs1)))
        | uu___2 ->
            let uu___3 =
              let uu___4 =
                FStarC_Class_Show.show FStarC_Syntax_Print.showable_term
                  bind_t in
              FStarC_Format.fmt2
                "Type of %s is not an arrow with >= 4 binders (%s)" bind_name
                uu___4 in
            FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
              FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
              (Obj.magic FStarC_Errors_Msg.is_error_message_string)
              (Obj.magic uu___3) in
      let uu___1 =
        if has_range_binders
        then
          (if (FStarC_List.length rest_bs) >= (Prims.of_int 2)
           then
             FStarC_List.splitAt
               ((FStarC_List.length rest_bs) - (Prims.of_int 2)) rest_bs
           else
             (let uu___2 =
                let uu___3 =
                  FStarC_Class_Show.show FStarC_Syntax_Print.showable_term
                    bind_t in
                FStarC_Format.fmt2
                  "Type of %s is not an arrow with >= 6 binders (%s)"
                  bind_name uu___3 in
              FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range
                r FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
                (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                (Obj.magic uu___2)))
        else (rest_bs, []) in
      (match uu___1 with
       | (rest_bs1, range_bs) ->
           let uu___2 =
             let uu___3 =
               let uu___4 =
                 FStarC_TypeChecker_Env.push_binders env (a_b :: b_b ::
                   rest_bs1) in
               let uu___5 =
                 FStarC_Syntax_Syntax.bv_to_name
                   a_b.FStarC_Syntax_Syntax.binder_bv in
               FStarC_TypeChecker_Util.fresh_effect_repr uu___4 r m_eff_name
                 m_sig_ts m_repr_ts (FStarC_Syntax_Syntax.U_name u_a) uu___5 in
             match uu___3 with
             | (repr, g) ->
                 let uu___4 =
                   let uu___5 =
                     FStarC_Syntax_Syntax.gen_bv "f"
                       FStar_Pervasives_Native.None repr in
                   FStarC_Syntax_Syntax.mk_binder uu___5 in
                 (uu___4, g) in
           (match uu___2 with
            | (f, guard_f) ->
                let uu___3 =
                  let x_a =
                    let uu___4 =
                      let uu___5 =
                        FStarC_Syntax_Syntax.bv_to_name
                          a_b.FStarC_Syntax_Syntax.binder_bv in
                      FStarC_Syntax_Syntax.gen_bv "x"
                        FStar_Pervasives_Native.None uu___5 in
                    FStarC_Syntax_Syntax.mk_binder uu___4 in
                  let uu___4 =
                    let uu___5 =
                      FStarC_TypeChecker_Env.push_binders env
                        (FStarC_List.op_At (a_b :: b_b :: rest_bs1) [x_a]) in
                    let uu___6 =
                      FStarC_Syntax_Syntax.bv_to_name
                        b_b.FStarC_Syntax_Syntax.binder_bv in
                    FStarC_TypeChecker_Util.fresh_effect_repr uu___5 r
                      n_eff_name n_sig_ts n_repr_ts
                      (FStarC_Syntax_Syntax.U_name u_b) uu___6 in
                  match uu___4 with
                  | (repr, g) ->
                      let uu___5 =
                        let uu___6 =
                          let uu___7 =
                            let uu___8 = FStarC_Syntax_Syntax.mk_Total repr in
                            FStarC_Syntax_Util.arrow [x_a] uu___8 in
                          FStarC_Syntax_Syntax.gen_bv "g"
                            FStar_Pervasives_Native.None uu___7 in
                        FStarC_Syntax_Syntax.mk_binder uu___6 in
                      (uu___5, g) in
                (match uu___3 with
                 | (g, guard_g) ->
                     let uu___4 =
                       let uu___5 =
                         FStarC_TypeChecker_Env.push_binders env (a_b :: b_b
                           :: rest_bs1) in
                       let uu___6 =
                         FStarC_Syntax_Syntax.bv_to_name
                           b_b.FStarC_Syntax_Syntax.binder_bv in
                       FStarC_TypeChecker_Util.fresh_effect_repr uu___5 r
                         p_eff_name p_sig_ts p_repr_ts
                         (FStarC_Syntax_Syntax.U_name u_b) uu___6 in
                     (match uu___4 with
                      | (return_repr, guard_return_repr) ->
                          let uu___5 =
                            let uu___6 =
                              FStarC_TypeChecker_Env.push_binders env (a_b ::
                                b_b :: rest_bs1) in
                            pure_wp_uvar uu___6 return_repr
                              (FStarC_Format.fmt1
                                 "implicit for pure_wp in checking bind %s"
                                 bind_name) r in
                          (match uu___5 with
                           | (pure_wp_uvar1, g_pure_wp_uvar) ->
                               let k =
                                 let uu___6 =
                                   let uu___7 =
                                     let uu___8 =
                                       let uu___9 =
                                         FStarC_TypeChecker_Env.new_u_univ () in
                                       [uu___9] in
                                     {
                                       FStarC_Syntax_Syntax.comp_univs =
                                         uu___8;
                                       FStarC_Syntax_Syntax.effect_name =
                                         FStarC_Parser_Const.effect_PURE_lid;
                                       FStarC_Syntax_Syntax.result_typ =
                                         return_repr;
                                       FStarC_Syntax_Syntax.effect_args =
                                         [FStarC_Syntax_Syntax.as_arg
                                            pure_wp_uvar1];
                                       FStarC_Syntax_Syntax.flags = []
                                     } in
                                   FStarC_Syntax_Syntax.mk_Comp uu___7 in
                                 FStarC_Syntax_Util.arrow (a_b :: b_b ::
                                   (FStarC_List.op_At rest_bs1
                                      (FStarC_List.op_At range_bs [f; g])))
                                   uu___6 in
                               let guard_eq =
                                 let uu___6 =
                                   FStarC_TypeChecker_Rel.teq_nosmt env k
                                     bind_t in
                                 match uu___6 with
                                 | FStar_Pervasives_Native.None ->
                                     let uu___7 =
                                       let uu___8 =
                                         FStarC_Class_Show.show
                                           FStarC_Syntax_Print.showable_term
                                           bind_t in
                                       FStarC_Format.fmt2
                                         "Unexpected type of %s (%s)\n"
                                         bind_name uu___8 in
                                     FStarC_Errors.raise_error
                                       FStarC_Class_HasRange.hasRange_range r
                                       FStarC_Errors_Codes.Fatal_UnexpectedEffect
                                       ()
                                       (Obj.magic
                                          FStarC_Errors_Msg.is_error_message_string)
                                       (Obj.magic uu___7)
                                 | FStar_Pervasives_Native.Some g1 -> g1 in
                               ((let uu___7 =
                                   FStarC_TypeChecker_Env.conj_guards
                                     [guard_f;
                                     guard_g;
                                     guard_return_repr;
                                     g_pure_wp_uvar;
                                     guard_eq] in
                                 FStarC_TypeChecker_Rel.force_trivial_guard
                                   env uu___7);
                                (let k1 =
                                   let uu___7 =
                                     FStarC_TypeChecker_Normalize.remove_uvar_solutions
                                       env k in
                                   FStarC_Syntax_Subst.compress uu___7 in
                                 let lopt =
                                   bind_combinator_kind env m_eff_name
                                     n_eff_name p_eff_name m_sig_ts n_sig_ts
                                     p_sig_ts m_repr_ts n_repr_ts p_repr_ts
                                     bind_us k1 num_effect_params
                                     has_range_binders in
                                 let kind =
                                   match lopt with
                                   | FStar_Pervasives_Native.None ->
                                       (log_ad_hoc_combinator_warning
                                          bind_name r;
                                        FStarC_Syntax_Syntax.Ad_hoc_combinator)
                                   | FStar_Pervasives_Native.Some l ->
                                       FStarC_Syntax_Syntax.Substitutive_combinator
                                         l in
                                 (let uu___8 =
                                    let uu___9 = FStarC_Debug.medium () in
                                    if uu___9
                                    then true
                                    else
                                      FStarC_Effect.op_Bang
                                        dbg_LayeredEffectsTc in
                                  if uu___8
                                  then
                                    let uu___9 =
                                      FStarC_Class_Show.show
                                        FStarC_Syntax_Syntax.showable_indexed_effect_combinator_kind
                                        kind in
                                    FStarC_Format.print2
                                      "Bind %s has %s kind\n" bind_name
                                      uu___9
                                  else ());
                                 (k1, kind))))))))
let subcomp_combinator_kind (env : FStarC_TypeChecker_Env.env)
  (m_eff_name : FStarC_Ident.lident) (n_eff_name : FStarC_Ident.lident)
  (m_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (n_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (m_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (n_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (u : FStarC_Syntax_Syntax.univ_name) (k : FStarC_Syntax_Syntax.typ)
  (num_effect_params : Prims.int) :
  FStarC_Syntax_Syntax.indexed_effect_combinator_kind
    FStar_Pervasives_Native.option=
  let uu___ = FStarC_Syntax_Util.arrow_formals_comp k in
  match uu___ with
  | (a_b::rest_bs, k_c) ->
      let uu___1 =
        if num_effect_params = Prims.int_zero
        then FStar_Pervasives_Native.Some ([], [], rest_bs)
        else
          (let uu___2 =
             FStarC_TypeChecker_Env.inst_tscheme_with m_sig_ts
               [FStarC_Syntax_Syntax.U_name u] in
           match uu___2 with
           | (uu___3, sig1) ->
               let uu___4 = FStarC_Syntax_Util.arrow_formals sig1 in
               (match uu___4 with
                | (uu___5::sig_bs, uu___6) ->
                    let sig_effect_params_bs =
                      FStar_Pervasives_Native.fst
                        (FStarC_List.splitAt num_effect_params sig_bs) in
                    let uu___7 =
                      FStarC_List.splitAt num_effect_params rest_bs in
                    (match uu___7 with
                     | (eff_params_bs, rest_bs1) ->
                         let uu___8 =
                           eq_binders env sig_effect_params_bs eff_params_bs in
                         op_let_Question uu___8
                           (fun eff_params_bs_kinds ->
                              FStar_Pervasives_Native.Some
                                (eff_params_bs, eff_params_bs_kinds,
                                  rest_bs1))))) in
      op_let_Question uu___1
        (fun uu___2 ->
           match uu___2 with
           | (eff_params_bs, eff_params_bs_kinds, rest_bs1) ->
               let uu___3 =
                 let f_sig_bs =
                   let uu___4 =
                     FStarC_TypeChecker_Env.inst_tscheme_with m_sig_ts
                       [FStarC_Syntax_Syntax.U_name u] in
                   match uu___4 with
                   | (uu___5, sig1) ->
                       let uu___6 =
                         let uu___7 = FStarC_Syntax_Util.arrow_formals sig1 in
                         FStar_Pervasives_Native.fst uu___7 in
                       (match uu___6 with
                        | a::bs ->
                            let uu___7 =
                              FStarC_List.splitAt num_effect_params bs in
                            (match uu___7 with
                             | (sig_bs, bs1) ->
                                 let ss =
                                   let uu___8 =
                                     let uu___9 =
                                       let uu___10 =
                                         let uu___11 =
                                           FStarC_Syntax_Syntax.bv_to_name
                                             a_b.FStarC_Syntax_Syntax.binder_bv in
                                         ((a.FStarC_Syntax_Syntax.binder_bv),
                                           uu___11) in
                                       FStarC_Syntax_Syntax.NT uu___10 in
                                     [uu___9] in
                                   FStarC_List.fold_left2
                                     (fun ss1 sig_b b ->
                                        let uu___9 =
                                          let uu___10 =
                                            let uu___11 =
                                              let uu___12 =
                                                FStarC_Syntax_Syntax.bv_to_name
                                                  b.FStarC_Syntax_Syntax.binder_bv in
                                              ((sig_b.FStarC_Syntax_Syntax.binder_bv),
                                                uu___12) in
                                            FStarC_Syntax_Syntax.NT uu___11 in
                                          [uu___10] in
                                        FStarC_List.op_At ss1 uu___9) uu___8
                                     sig_bs eff_params_bs in
                                 FStarC_Syntax_Subst.subst_binders ss bs1)) in
                 op_let_Question
                   (if
                      (FStarC_List.length rest_bs1) <
                        (FStarC_List.length f_sig_bs)
                    then FStar_Pervasives_Native.None
                    else
                      FStar_Pervasives_Native.Some
                        (FStarC_List.splitAt (FStarC_List.length f_sig_bs)
                           rest_bs1))
                   (fun uu___4 ->
                      match uu___4 with
                      | (f_bs, rest_bs2) ->
                          let uu___5 = eq_binders env f_sig_bs f_bs in
                          op_let_Question uu___5
                            (fun f_bs_kinds ->
                               FStar_Pervasives_Native.Some
                                 (f_bs, f_bs_kinds, rest_bs2))) in
               op_let_Question uu___3
                 (fun uu___4 ->
                    match uu___4 with
                    | (f_bs, f_bs_kinds, rest_bs2) ->
                        op_let_Question
                          (if Prims.uu___is_Cons rest_bs2
                           then
                             let uu___5 =
                               FStarC_List.splitAt
                                 ((FStarC_List.length rest_bs2) -
                                    Prims.int_one) rest_bs2 in
                             match uu___5 with
                             | (rest_bs3, f_b::[]) ->
                                 FStar_Pervasives_Native.Some (rest_bs3, f_b)
                           else FStar_Pervasives_Native.None)
                          (fun uu___5 ->
                             match uu___5 with
                             | (rest_bs3, f_b) ->
                                 let uu___6 =
                                   let expected_f_b_sort =
                                     match m_repr_ts with
                                     | FStar_Pervasives_Native.Some repr_ts
                                         ->
                                         let uu___7 =
                                           FStarC_TypeChecker_Env.inst_tscheme_with
                                             repr_ts
                                             [FStarC_Syntax_Syntax.U_name u] in
                                         (match uu___7 with
                                          | (uu___8, t) ->
                                              let uu___9 =
                                                let uu___10 =
                                                  let uu___11 =
                                                    FStarC_Syntax_Syntax.bv_to_name
                                                      a_b.FStarC_Syntax_Syntax.binder_bv in
                                                  FStarC_Syntax_Syntax.as_arg
                                                    uu___11 in
                                                let uu___11 =
                                                  FStarC_List.map
                                                    (fun uu___12 ->
                                                       match uu___12 with
                                                       | {
                                                           FStarC_Syntax_Syntax.binder_bv
                                                             = b;
                                                           FStarC_Syntax_Syntax.binder_qual
                                                             = uu___13;
                                                           FStarC_Syntax_Syntax.binder_positivity
                                                             = uu___14;
                                                           FStarC_Syntax_Syntax.binder_attrs
                                                             = uu___15;_}
                                                           ->
                                                           let uu___16 =
                                                             FStarC_Syntax_Syntax.bv_to_name
                                                               b in
                                                           FStarC_Syntax_Syntax.as_arg
                                                             uu___16)
                                                    (FStarC_List.op_At
                                                       eff_params_bs f_bs) in
                                                uu___10 :: uu___11 in
                                              FStarC_Syntax_Syntax.mk_Tm_app
                                                t uu___9
                                                FStarC_Range_Type.dummyRange)
                                     | FStar_Pervasives_Native.None ->
                                         let uu___7 =
                                           let uu___8 =
                                             FStarC_Syntax_Syntax.null_binder
                                               FStarC_Syntax_Syntax.t_unit in
                                           [uu___8] in
                                         let uu___8 =
                                           let uu___9 =
                                             let uu___10 =
                                               FStarC_Syntax_Syntax.bv_to_name
                                                 a_b.FStarC_Syntax_Syntax.binder_bv in
                                             let uu___11 =
                                               FStarC_List.map
                                                 (fun b ->
                                                    let uu___12 =
                                                      FStarC_Syntax_Syntax.bv_to_name
                                                        b.FStarC_Syntax_Syntax.binder_bv in
                                                    FStarC_Syntax_Syntax.as_arg
                                                      uu___12)
                                                 (FStarC_List.op_At
                                                    eff_params_bs f_bs) in
                                             {
                                               FStarC_Syntax_Syntax.comp_univs
                                                 =
                                                 [FStarC_Syntax_Syntax.U_name
                                                    u];
                                               FStarC_Syntax_Syntax.effect_name
                                                 = m_eff_name;
                                               FStarC_Syntax_Syntax.result_typ
                                                 = uu___10;
                                               FStarC_Syntax_Syntax.effect_args
                                                 = uu___11;
                                               FStarC_Syntax_Syntax.flags =
                                                 []
                                             } in
                                           FStarC_Syntax_Syntax.mk_Comp
                                             uu___9 in
                                         FStarC_Syntax_Util.arrow uu___7
                                           uu___8 in
                                   let uu___7 =
                                     let uu___8 =
                                       FStarC_TypeChecker_TermEqAndSimplify.eq_tm
                                         env
                                         (f_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                                         expected_f_b_sort in
                                     uu___8 =
                                       FStarC_TypeChecker_TermEqAndSimplify.Equal in
                                   if uu___7
                                   then FStar_Pervasives_Native.Some ()
                                   else FStar_Pervasives_Native.None in
                                 op_let_Question uu___6
                                   (fun _f_b_ok_ ->
                                      let check_ret_t f_or_g_bs =
                                        let expected_t =
                                          match n_repr_ts with
                                          | FStar_Pervasives_Native.Some
                                              repr_ts ->
                                              let uu___7 =
                                                FStarC_TypeChecker_Env.inst_tscheme_with
                                                  repr_ts
                                                  [FStarC_Syntax_Syntax.U_name
                                                     u] in
                                              (match uu___7 with
                                               | (uu___8, t) ->
                                                   let uu___9 =
                                                     let uu___10 =
                                                       let uu___11 =
                                                         FStarC_Syntax_Syntax.bv_to_name
                                                           a_b.FStarC_Syntax_Syntax.binder_bv in
                                                       FStarC_Syntax_Syntax.as_arg
                                                         uu___11 in
                                                     let uu___11 =
                                                       FStarC_List.map
                                                         (fun uu___12 ->
                                                            match uu___12
                                                            with
                                                            | {
                                                                FStarC_Syntax_Syntax.binder_bv
                                                                  = b;
                                                                FStarC_Syntax_Syntax.binder_qual
                                                                  = uu___13;
                                                                FStarC_Syntax_Syntax.binder_positivity
                                                                  = uu___14;
                                                                FStarC_Syntax_Syntax.binder_attrs
                                                                  = uu___15;_}
                                                                ->
                                                                let uu___16 =
                                                                  FStarC_Syntax_Syntax.bv_to_name
                                                                    b in
                                                                FStarC_Syntax_Syntax.as_arg
                                                                  uu___16)
                                                         (FStarC_List.op_At
                                                            eff_params_bs
                                                            f_or_g_bs) in
                                                     uu___10 :: uu___11 in
                                                   FStarC_Syntax_Syntax.mk_Tm_app
                                                     t uu___9
                                                     FStarC_Range_Type.dummyRange)
                                          | FStar_Pervasives_Native.None ->
                                              let uu___7 =
                                                let uu___8 =
                                                  FStarC_Syntax_Syntax.null_binder
                                                    FStarC_Syntax_Syntax.t_unit in
                                                [uu___8] in
                                              let uu___8 =
                                                let uu___9 =
                                                  let uu___10 =
                                                    FStarC_Syntax_Syntax.bv_to_name
                                                      a_b.FStarC_Syntax_Syntax.binder_bv in
                                                  let uu___11 =
                                                    FStarC_List.map
                                                      (fun b ->
                                                         let uu___12 =
                                                           FStarC_Syntax_Syntax.bv_to_name
                                                             b.FStarC_Syntax_Syntax.binder_bv in
                                                         FStarC_Syntax_Syntax.as_arg
                                                           uu___12)
                                                      (FStarC_List.op_At
                                                         eff_params_bs
                                                         f_or_g_bs) in
                                                  {
                                                    FStarC_Syntax_Syntax.comp_univs
                                                      =
                                                      [FStarC_Syntax_Syntax.U_name
                                                         u];
                                                    FStarC_Syntax_Syntax.effect_name
                                                      = n_eff_name;
                                                    FStarC_Syntax_Syntax.result_typ
                                                      = uu___10;
                                                    FStarC_Syntax_Syntax.effect_args
                                                      = uu___11;
                                                    FStarC_Syntax_Syntax.flags
                                                      = []
                                                  } in
                                                FStarC_Syntax_Syntax.mk_Comp
                                                  uu___9 in
                                              FStarC_Syntax_Util.arrow uu___7
                                                uu___8 in
                                        let uu___7 =
                                          let uu___8 =
                                            FStarC_TypeChecker_TermEqAndSimplify.eq_tm
                                              env
                                              (FStarC_Syntax_Util.comp_result
                                                 k_c) expected_t in
                                          uu___8 =
                                            FStarC_TypeChecker_TermEqAndSimplify.Equal in
                                        if uu___7
                                        then FStar_Pervasives_Native.Some ()
                                        else FStar_Pervasives_Native.None in
                                      let uu___7 =
                                        let uu___8 = check_ret_t f_bs in
                                        FStar_Pervasives_Native.uu___is_Some
                                          uu___8 in
                                      if uu___7
                                      then
                                        FStar_Pervasives_Native.Some
                                          FStarC_Syntax_Syntax.Substitutive_invariant_combinator
                                      else
                                        (let uu___8 =
                                           let g_sig_bs =
                                             let uu___9 =
                                               FStarC_TypeChecker_Env.inst_tscheme_with
                                                 n_sig_ts
                                                 [FStarC_Syntax_Syntax.U_name
                                                    u] in
                                             match uu___9 with
                                             | (uu___10, sig1) ->
                                                 let uu___11 =
                                                   let uu___12 =
                                                     FStarC_Syntax_Util.arrow_formals
                                                       sig1 in
                                                   FStar_Pervasives_Native.fst
                                                     uu___12 in
                                                 (match uu___11 with
                                                  | a::bs ->
                                                      let uu___12 =
                                                        FStarC_List.splitAt
                                                          num_effect_params
                                                          bs in
                                                      (match uu___12 with
                                                       | (sig_bs, bs1) ->
                                                           let ss =
                                                             let uu___13 =
                                                               let uu___14 =
                                                                 let uu___15
                                                                   =
                                                                   let uu___16
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    a_b.FStarC_Syntax_Syntax.binder_bv in
                                                                   ((a.FStarC_Syntax_Syntax.binder_bv),
                                                                    uu___16) in
                                                                 FStarC_Syntax_Syntax.NT
                                                                   uu___15 in
                                                               [uu___14] in
                                                             FStarC_List.fold_left2
                                                               (fun ss1 sig_b
                                                                  b ->
                                                                  let uu___14
                                                                    =
                                                                    let uu___15
                                                                    =
                                                                    let uu___16
                                                                    =
                                                                    let uu___17
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b.FStarC_Syntax_Syntax.binder_bv in
                                                                    ((sig_b.FStarC_Syntax_Syntax.binder_bv),
                                                                    uu___17) in
                                                                    FStarC_Syntax_Syntax.NT
                                                                    uu___16 in
                                                                    [uu___15] in
                                                                  FStarC_List.op_At
                                                                    ss1
                                                                    uu___14)
                                                               uu___13 sig_bs
                                                               eff_params_bs in
                                                           FStarC_Syntax_Subst.subst_binders
                                                             ss bs1)) in
                                           op_let_Question
                                             (if
                                                (FStarC_List.length rest_bs3)
                                                  <
                                                  (FStarC_List.length
                                                     g_sig_bs)
                                              then
                                                FStar_Pervasives_Native.None
                                              else
                                                FStar_Pervasives_Native.Some
                                                  (FStarC_List.splitAt
                                                     (FStarC_List.length
                                                        g_sig_bs) rest_bs3))
                                             (fun uu___9 ->
                                                match uu___9 with
                                                | (g_bs, rest_bs4) ->
                                                    let uu___10 =
                                                      eq_binders env g_sig_bs
                                                        g_bs in
                                                    op_let_Question uu___10
                                                      (fun g_bs_kinds ->
                                                         FStar_Pervasives_Native.Some
                                                           (g_bs, g_bs_kinds,
                                                             rest_bs4))) in
                                         op_let_Question uu___8
                                           (fun uu___9 ->
                                              match uu___9 with
                                              | (g_bs, g_bs_kinds, rest_bs4)
                                                  ->
                                                  let uu___10 =
                                                    check_ret_t g_bs in
                                                  op_let_Question uu___10
                                                    (fun _ret_t_ok_ ->
                                                       let rest_kinds =
                                                         FStarC_List.map
                                                           (fun uu___11 ->
                                                              FStarC_Syntax_Syntax.Ad_hoc_binder)
                                                           rest_bs4 in
                                                       FStar_Pervasives_Native.Some
                                                         (FStarC_Syntax_Syntax.Substitutive_combinator
                                                            (FStarC_List.op_At
                                                               [FStarC_Syntax_Syntax.Type_binder]
                                                               (FStarC_List.op_At
                                                                  eff_params_bs_kinds
                                                                  (FStarC_List.op_At
                                                                    f_bs_kinds
                                                                    (FStarC_List.op_At
                                                                    g_bs_kinds
                                                                    (FStarC_List.op_At
                                                                    rest_kinds
                                                                    [FStarC_Syntax_Syntax.Repr_binder])))))))))))))
let validate_indexed_effect_subcomp_shape (env : FStarC_TypeChecker_Env.env)
  (m_eff_name : FStarC_Ident.lident) (n_eff_name : FStarC_Ident.lident)
  (m_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (n_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (m_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (n_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (u : FStarC_Syntax_Syntax.univ_name) (subcomp_t : FStarC_Syntax_Syntax.typ)
  (num_effect_params : Prims.int) (r : FStarC_Range_Type.t) :
  (FStarC_Syntax_Syntax.typ *
    FStarC_Syntax_Syntax.indexed_effect_combinator_kind)=
  let subcomp_name =
    FStarC_Format.fmt2 "%s <: %s" (FStarC_Ident.string_of_lid m_eff_name)
      (FStarC_Ident.string_of_lid n_eff_name) in
  let a_b =
    let uu___ =
      let uu___1 =
        FStarC_Syntax_Util.type_with_u (FStarC_Syntax_Syntax.U_name u) in
      FStarC_Syntax_Syntax.gen_bv "a" FStar_Pervasives_Native.None uu___1 in
    FStarC_Syntax_Syntax.mk_binder uu___ in
  let rest_bs =
    let uu___ =
      let uu___1 = FStarC_Syntax_Subst.compress subcomp_t in
      uu___1.FStarC_Syntax_Syntax.n in
    match uu___ with
    | FStarC_Syntax_Syntax.Tm_arrow
        { FStarC_Syntax_Syntax.bs1 = bs;
          FStarC_Syntax_Syntax.comp = uu___1;_}
        when (FStarC_List.length bs) >= (Prims.of_int 2) ->
        let uu___2 = FStarC_Syntax_Subst.open_binders bs in
        (match uu___2 with
         | { FStarC_Syntax_Syntax.binder_bv = a;
             FStarC_Syntax_Syntax.binder_qual = uu___3;
             FStarC_Syntax_Syntax.binder_positivity = uu___4;
             FStarC_Syntax_Syntax.binder_attrs = uu___5;_}::bs1 ->
             let uu___6 =
               let uu___7 =
                 let uu___8 =
                   let uu___9 =
                     FStarC_Syntax_Syntax.bv_to_name
                       a_b.FStarC_Syntax_Syntax.binder_bv in
                   (a, uu___9) in
                 FStarC_Syntax_Syntax.NT uu___8 in
               [uu___7] in
             FStarC_Syntax_Subst.subst_binders uu___6
               (FStar_Pervasives_Native.fst
                  (FStarC_List.splitAt
                     ((FStarC_List.length bs1) - Prims.int_one) bs1)))
    | uu___1 ->
        let uu___2 =
          let uu___3 =
            FStarC_Class_Show.show FStarC_Syntax_Print.showable_term
              subcomp_t in
          FStarC_Format.fmt2
            "Type of %s is not an arrow with >= 2 binders (%s)" subcomp_name
            uu___3 in
        FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
          FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_string)
          (Obj.magic uu___2) in
  let uu___ =
    let uu___1 =
      let uu___2 = FStarC_TypeChecker_Env.push_binders env (a_b :: rest_bs) in
      let uu___3 =
        FStarC_Syntax_Syntax.bv_to_name a_b.FStarC_Syntax_Syntax.binder_bv in
      FStarC_TypeChecker_Util.fresh_effect_repr uu___2 r m_eff_name m_sig_ts
        m_repr_ts (FStarC_Syntax_Syntax.U_name u) uu___3 in
    match uu___1 with
    | (repr, g) ->
        let uu___2 =
          let uu___3 =
            FStarC_Syntax_Syntax.gen_bv "f" FStar_Pervasives_Native.None repr in
          FStarC_Syntax_Syntax.mk_binder uu___3 in
        (uu___2, g) in
  match uu___ with
  | (f, guard_f) ->
      let uu___1 =
        let uu___2 = FStarC_TypeChecker_Env.push_binders env (a_b :: rest_bs) in
        let uu___3 =
          FStarC_Syntax_Syntax.bv_to_name a_b.FStarC_Syntax_Syntax.binder_bv in
        FStarC_TypeChecker_Util.fresh_effect_repr uu___2 r n_eff_name
          n_sig_ts n_repr_ts (FStarC_Syntax_Syntax.U_name u) uu___3 in
      (match uu___1 with
       | (ret_t, guard_ret_t) ->
           let uu___2 =
             let uu___3 =
               FStarC_TypeChecker_Env.push_binders env (a_b :: rest_bs) in
             pure_wp_uvar uu___3 ret_t
               (FStarC_Format.fmt1 "implicit for pure_wp in checking %s"
                  subcomp_name) r in
           (match uu___2 with
            | (pure_wp_uvar1, guard_wp) ->
                let c =
                  let uu___3 =
                    let uu___4 =
                      let uu___5 = FStarC_TypeChecker_Env.new_u_univ () in
                      [uu___5] in
                    {
                      FStarC_Syntax_Syntax.comp_univs = uu___4;
                      FStarC_Syntax_Syntax.effect_name =
                        FStarC_Parser_Const.effect_PURE_lid;
                      FStarC_Syntax_Syntax.result_typ = ret_t;
                      FStarC_Syntax_Syntax.effect_args =
                        [FStarC_Syntax_Syntax.as_arg pure_wp_uvar1];
                      FStarC_Syntax_Syntax.flags = []
                    } in
                  FStarC_Syntax_Syntax.mk_Comp uu___3 in
                let k =
                  FStarC_Syntax_Util.arrow
                    (FStarC_List.op_At (a_b :: rest_bs) [f]) c in
                ((let uu___4 =
                    let uu___5 = FStarC_Debug.medium () in
                    if uu___5
                    then true
                    else FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
                  if uu___4
                  then
                    let uu___5 =
                      FStarC_Class_Show.show
                        FStarC_Syntax_Print.showable_term k in
                    FStarC_Format.print1
                      "Expected type of subcomp before unification: %s\n"
                      uu___5
                  else ());
                 (let guard_eq =
                    let uu___4 =
                      FStarC_TypeChecker_Rel.teq_nosmt env subcomp_t k in
                    match uu___4 with
                    | FStar_Pervasives_Native.None ->
                        let uu___5 =
                          let uu___6 =
                            FStarC_Class_Show.show
                              FStarC_Syntax_Print.showable_term subcomp_t in
                          FStarC_Format.fmt2 "Unexpected type of %s (%s)\n"
                            subcomp_name uu___6 in
                        FStarC_Errors.raise_error
                          FStarC_Class_HasRange.hasRange_range r
                          FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
                          (Obj.magic
                             FStarC_Errors_Msg.is_error_message_string)
                          (Obj.magic uu___5)
                    | FStar_Pervasives_Native.Some g -> g in
                  (let uu___5 =
                     FStarC_TypeChecker_Env.conj_guards
                       [guard_f; guard_ret_t; guard_wp; guard_eq] in
                   FStarC_TypeChecker_Rel.force_trivial_guard env uu___5);
                  (let k1 =
                     let uu___5 =
                       FStarC_TypeChecker_Normalize.remove_uvar_solutions env
                         k in
                     FStarC_Syntax_Subst.compress uu___5 in
                   let kopt =
                     subcomp_combinator_kind env m_eff_name n_eff_name
                       m_sig_ts n_sig_ts m_repr_ts n_repr_ts u k1
                       num_effect_params in
                   let kind =
                     match kopt with
                     | FStar_Pervasives_Native.None ->
                         (log_ad_hoc_combinator_warning subcomp_name r;
                          FStarC_Syntax_Syntax.Ad_hoc_combinator)
                     | FStar_Pervasives_Native.Some k2 -> k2 in
                   (let uu___6 =
                      let uu___7 = FStarC_Debug.medium () in
                      if uu___7
                      then true
                      else FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
                    if uu___6
                    then
                      let uu___7 =
                        FStarC_Class_Show.show
                          FStarC_Syntax_Syntax.showable_indexed_effect_combinator_kind
                          kind in
                      FStarC_Format.print2 "Subcomp %s has %s kind\n"
                        subcomp_name uu___7
                    else ());
                   (k1, kind))))))
let ite_combinator_kind (env : FStarC_TypeChecker_Env.env)
  (eff_name : FStarC_Ident.lident) (sig_ts : FStarC_Syntax_Syntax.tscheme)
  (repr_ts : FStarC_Syntax_Syntax.tscheme)
  (u : FStarC_Syntax_Syntax.univ_name) (tm : FStarC_Syntax_Syntax.term)
  (num_effect_params : Prims.int) :
  FStarC_Syntax_Syntax.indexed_effect_combinator_kind
    FStar_Pervasives_Native.option=
  let uu___ = FStarC_Syntax_Util.abs_formals tm in
  match uu___ with
  | (a_b::rest_bs, uu___1, uu___2) ->
      let uu___3 =
        if num_effect_params = Prims.int_zero
        then FStar_Pervasives_Native.Some ([], [], rest_bs)
        else
          (let uu___4 =
             FStarC_TypeChecker_Env.inst_tscheme_with sig_ts
               [FStarC_Syntax_Syntax.U_name u] in
           match uu___4 with
           | (uu___5, sig1) ->
               let uu___6 = FStarC_Syntax_Util.arrow_formals sig1 in
               (match uu___6 with
                | (uu___7::sig_bs, uu___8) ->
                    let sig_effect_params_bs =
                      FStar_Pervasives_Native.fst
                        (FStarC_List.splitAt num_effect_params sig_bs) in
                    let uu___9 =
                      FStarC_List.splitAt num_effect_params rest_bs in
                    (match uu___9 with
                     | (eff_params_bs, rest_bs1) ->
                         let uu___10 =
                           eq_binders env sig_effect_params_bs eff_params_bs in
                         op_let_Question uu___10
                           (fun eff_params_bs_kinds ->
                              FStar_Pervasives_Native.Some
                                (eff_params_bs, eff_params_bs_kinds,
                                  rest_bs1))))) in
      op_let_Question uu___3
        (fun uu___4 ->
           match uu___4 with
           | (eff_params_bs, eff_params_bs_kinds, rest_bs1) ->
               let uu___5 =
                 let f_sig_bs =
                   let uu___6 =
                     FStarC_TypeChecker_Env.inst_tscheme_with sig_ts
                       [FStarC_Syntax_Syntax.U_name u] in
                   match uu___6 with
                   | (uu___7, sig1) ->
                       let uu___8 =
                         let uu___9 = FStarC_Syntax_Util.arrow_formals sig1 in
                         FStar_Pervasives_Native.fst uu___9 in
                       (match uu___8 with
                        | a::bs ->
                            let uu___9 =
                              FStarC_List.splitAt num_effect_params bs in
                            (match uu___9 with
                             | (sig_bs, bs1) ->
                                 let ss =
                                   let uu___10 =
                                     let uu___11 =
                                       let uu___12 =
                                         let uu___13 =
                                           FStarC_Syntax_Syntax.bv_to_name
                                             a_b.FStarC_Syntax_Syntax.binder_bv in
                                         ((a.FStarC_Syntax_Syntax.binder_bv),
                                           uu___13) in
                                       FStarC_Syntax_Syntax.NT uu___12 in
                                     [uu___11] in
                                   FStarC_List.fold_left2
                                     (fun ss1 sig_b b ->
                                        let uu___11 =
                                          let uu___12 =
                                            let uu___13 =
                                              let uu___14 =
                                                FStarC_Syntax_Syntax.bv_to_name
                                                  b.FStarC_Syntax_Syntax.binder_bv in
                                              ((sig_b.FStarC_Syntax_Syntax.binder_bv),
                                                uu___14) in
                                            FStarC_Syntax_Syntax.NT uu___13 in
                                          [uu___12] in
                                        FStarC_List.op_At ss1 uu___11)
                                     uu___10 sig_bs eff_params_bs in
                                 FStarC_Syntax_Subst.subst_binders ss bs1)) in
                 op_let_Question
                   (if
                      (FStarC_List.length rest_bs1) <
                        (FStarC_List.length f_sig_bs)
                    then FStar_Pervasives_Native.None
                    else
                      FStar_Pervasives_Native.Some
                        (FStarC_List.splitAt (FStarC_List.length f_sig_bs)
                           rest_bs1))
                   (fun uu___6 ->
                      match uu___6 with
                      | (f_bs, rest_bs2) ->
                          let uu___7 = eq_binders env f_sig_bs f_bs in
                          op_let_Question uu___7
                            (fun f_bs_kinds ->
                               FStar_Pervasives_Native.Some
                                 (f_bs, f_bs_kinds, rest_bs2))) in
               op_let_Question uu___5
                 (fun uu___6 ->
                    match uu___6 with
                    | (f_bs, f_bs_kinds, rest_bs2) ->
                        op_let_Question
                          (if
                             (FStarC_List.length rest_bs2) >=
                               (Prims.of_int 3)
                           then
                             FStar_Pervasives_Native.Some
                               (FStarC_List.splitAt
                                  ((FStarC_List.length rest_bs2) -
                                     (Prims.of_int 3)) rest_bs2)
                           else FStar_Pervasives_Native.None)
                          (fun uu___7 ->
                             match uu___7 with
                             | (rest_bs3, f_b::g_b::p_b::[]) ->
                                 let uu___8 =
                                   let expected_f_b_sort =
                                     let uu___9 =
                                       FStarC_TypeChecker_Env.inst_tscheme_with
                                         repr_ts
                                         [FStarC_Syntax_Syntax.U_name u] in
                                     match uu___9 with
                                     | (uu___10, t) ->
                                         let uu___11 =
                                           let uu___12 =
                                             let uu___13 =
                                               FStarC_Syntax_Syntax.bv_to_name
                                                 a_b.FStarC_Syntax_Syntax.binder_bv in
                                             FStarC_Syntax_Syntax.as_arg
                                               uu___13 in
                                           let uu___13 =
                                             FStarC_List.map
                                               (fun uu___14 ->
                                                  match uu___14 with
                                                  | {
                                                      FStarC_Syntax_Syntax.binder_bv
                                                        = b;
                                                      FStarC_Syntax_Syntax.binder_qual
                                                        = uu___15;
                                                      FStarC_Syntax_Syntax.binder_positivity
                                                        = uu___16;
                                                      FStarC_Syntax_Syntax.binder_attrs
                                                        = uu___17;_}
                                                      ->
                                                      let uu___18 =
                                                        FStarC_Syntax_Syntax.bv_to_name
                                                          b in
                                                      FStarC_Syntax_Syntax.as_arg
                                                        uu___18)
                                               (FStarC_List.op_At
                                                  eff_params_bs f_bs) in
                                           uu___12 :: uu___13 in
                                         FStarC_Syntax_Syntax.mk_Tm_app t
                                           uu___11
                                           FStarC_Range_Type.dummyRange in
                                   let uu___9 =
                                     let uu___10 =
                                       FStarC_TypeChecker_TermEqAndSimplify.eq_tm
                                         env
                                         (f_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                                         expected_f_b_sort in
                                     uu___10 =
                                       FStarC_TypeChecker_TermEqAndSimplify.Equal in
                                   if uu___9
                                   then FStar_Pervasives_Native.Some ()
                                   else FStar_Pervasives_Native.None in
                                 op_let_Question uu___8
                                   (fun _f_b_ok_ ->
                                      let check_g_b f_or_g_bs =
                                        let expected_g_b_sort =
                                          let uu___9 =
                                            FStarC_TypeChecker_Env.inst_tscheme_with
                                              repr_ts
                                              [FStarC_Syntax_Syntax.U_name u] in
                                          match uu___9 with
                                          | (uu___10, t) ->
                                              let uu___11 =
                                                let uu___12 =
                                                  let uu___13 =
                                                    FStarC_Syntax_Syntax.bv_to_name
                                                      a_b.FStarC_Syntax_Syntax.binder_bv in
                                                  FStarC_Syntax_Syntax.as_arg
                                                    uu___13 in
                                                let uu___13 =
                                                  FStarC_List.map
                                                    (fun uu___14 ->
                                                       match uu___14 with
                                                       | {
                                                           FStarC_Syntax_Syntax.binder_bv
                                                             = b;
                                                           FStarC_Syntax_Syntax.binder_qual
                                                             = uu___15;
                                                           FStarC_Syntax_Syntax.binder_positivity
                                                             = uu___16;
                                                           FStarC_Syntax_Syntax.binder_attrs
                                                             = uu___17;_}
                                                           ->
                                                           let uu___18 =
                                                             FStarC_Syntax_Syntax.bv_to_name
                                                               b in
                                                           FStarC_Syntax_Syntax.as_arg
                                                             uu___18)
                                                    (FStarC_List.op_At
                                                       eff_params_bs
                                                       f_or_g_bs) in
                                                uu___12 :: uu___13 in
                                              FStarC_Syntax_Syntax.mk_Tm_app
                                                t uu___11
                                                FStarC_Range_Type.dummyRange in
                                        let uu___9 =
                                          let uu___10 =
                                            FStarC_TypeChecker_TermEqAndSimplify.eq_tm
                                              env
                                              (g_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                                              expected_g_b_sort in
                                          uu___10 =
                                            FStarC_TypeChecker_TermEqAndSimplify.Equal in
                                        if uu___9
                                        then FStar_Pervasives_Native.Some ()
                                        else FStar_Pervasives_Native.None in
                                      let uu___9 =
                                        let uu___10 = check_g_b f_bs in
                                        FStar_Pervasives_Native.uu___is_Some
                                          uu___10 in
                                      if uu___9
                                      then
                                        FStar_Pervasives_Native.Some
                                          FStarC_Syntax_Syntax.Substitutive_invariant_combinator
                                      else
                                        (let uu___10 =
                                           let g_sig_bs =
                                             let uu___11 =
                                               FStarC_TypeChecker_Env.inst_tscheme_with
                                                 sig_ts
                                                 [FStarC_Syntax_Syntax.U_name
                                                    u] in
                                             match uu___11 with
                                             | (uu___12, sig1) ->
                                                 let uu___13 =
                                                   let uu___14 =
                                                     FStarC_Syntax_Util.arrow_formals
                                                       sig1 in
                                                   FStar_Pervasives_Native.fst
                                                     uu___14 in
                                                 (match uu___13 with
                                                  | a::bs ->
                                                      let uu___14 =
                                                        FStarC_List.splitAt
                                                          num_effect_params
                                                          bs in
                                                      (match uu___14 with
                                                       | (sig_bs, bs1) ->
                                                           let ss =
                                                             let uu___15 =
                                                               let uu___16 =
                                                                 let uu___17
                                                                   =
                                                                   let uu___18
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    a_b.FStarC_Syntax_Syntax.binder_bv in
                                                                   ((a.FStarC_Syntax_Syntax.binder_bv),
                                                                    uu___18) in
                                                                 FStarC_Syntax_Syntax.NT
                                                                   uu___17 in
                                                               [uu___16] in
                                                             FStarC_List.fold_left2
                                                               (fun ss1 sig_b
                                                                  b ->
                                                                  let uu___16
                                                                    =
                                                                    let uu___17
                                                                    =
                                                                    let uu___18
                                                                    =
                                                                    let uu___19
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b.FStarC_Syntax_Syntax.binder_bv in
                                                                    ((sig_b.FStarC_Syntax_Syntax.binder_bv),
                                                                    uu___19) in
                                                                    FStarC_Syntax_Syntax.NT
                                                                    uu___18 in
                                                                    [uu___17] in
                                                                  FStarC_List.op_At
                                                                    ss1
                                                                    uu___16)
                                                               uu___15 sig_bs
                                                               eff_params_bs in
                                                           FStarC_Syntax_Subst.subst_binders
                                                             ss bs1)) in
                                           op_let_Question
                                             (if
                                                (FStarC_List.length rest_bs3)
                                                  <
                                                  (FStarC_List.length
                                                     g_sig_bs)
                                              then
                                                FStar_Pervasives_Native.None
                                              else
                                                FStar_Pervasives_Native.Some
                                                  (FStarC_List.splitAt
                                                     (FStarC_List.length
                                                        g_sig_bs) rest_bs3))
                                             (fun uu___11 ->
                                                match uu___11 with
                                                | (g_bs, rest_bs4) ->
                                                    let uu___12 =
                                                      eq_binders env g_sig_bs
                                                        g_bs in
                                                    op_let_Question uu___12
                                                      (fun g_bs_kinds ->
                                                         FStar_Pervasives_Native.Some
                                                           (g_bs, g_bs_kinds,
                                                             rest_bs4))) in
                                         op_let_Question uu___10
                                           (fun uu___11 ->
                                              match uu___11 with
                                              | (g_bs, g_bs_kinds, rest_bs4)
                                                  ->
                                                  let uu___12 =
                                                    check_g_b g_bs in
                                                  op_let_Question uu___12
                                                    (fun _g_b_ok_ ->
                                                       let rest_kinds =
                                                         FStarC_List.map
                                                           (fun uu___13 ->
                                                              FStarC_Syntax_Syntax.Ad_hoc_binder)
                                                           rest_bs4 in
                                                       FStar_Pervasives_Native.Some
                                                         (FStarC_Syntax_Syntax.Substitutive_combinator
                                                            (FStarC_List.op_At
                                                               [FStarC_Syntax_Syntax.Type_binder]
                                                               (FStarC_List.op_At
                                                                  eff_params_bs_kinds
                                                                  (FStarC_List.op_At
                                                                    f_bs_kinds
                                                                    (FStarC_List.op_At
                                                                    g_bs_kinds
                                                                    (FStarC_List.op_At
                                                                    rest_kinds
                                                                    [FStarC_Syntax_Syntax.Repr_binder;
                                                                    FStarC_Syntax_Syntax.Repr_binder;
                                                                    FStarC_Syntax_Syntax.Substitutive_binder])))))))))))))
let validate_indexed_effect_ite_shape (env : FStarC_TypeChecker_Env.env)
  (eff_name : FStarC_Ident.lident) (sig_ts : FStarC_Syntax_Syntax.tscheme)
  (repr_ts : FStarC_Syntax_Syntax.tscheme)
  (u : FStarC_Syntax_Syntax.univ_name) (ite_ty : FStarC_Syntax_Syntax.typ)
  (ite_tm : FStarC_Syntax_Syntax.term) (num_effect_params : Prims.int)
  (r : FStarC_Range_Type.t) :
  (FStarC_Syntax_Syntax.term *
    FStarC_Syntax_Syntax.indexed_effect_combinator_kind)=
  let ite_name =
    FStarC_Format.fmt1 "ite_%s" (FStarC_Ident.string_of_lid eff_name) in
  let a_b =
    let uu___ =
      let uu___1 =
        FStarC_Syntax_Util.type_with_u (FStarC_Syntax_Syntax.U_name u) in
      FStarC_Syntax_Syntax.gen_bv "a" FStar_Pervasives_Native.None uu___1 in
    FStarC_Syntax_Syntax.mk_binder uu___ in
  let rest_bs =
    let uu___ =
      let uu___1 = FStarC_Syntax_Subst.compress ite_ty in
      uu___1.FStarC_Syntax_Syntax.n in
    match uu___ with
    | FStarC_Syntax_Syntax.Tm_arrow
        { FStarC_Syntax_Syntax.bs1 = bs;
          FStarC_Syntax_Syntax.comp = uu___1;_}
        when (FStarC_List.length bs) >= (Prims.of_int 4) ->
        let uu___2 = FStarC_Syntax_Subst.open_binders bs in
        (match uu___2 with
         | { FStarC_Syntax_Syntax.binder_bv = a;
             FStarC_Syntax_Syntax.binder_qual = uu___3;
             FStarC_Syntax_Syntax.binder_positivity = uu___4;
             FStarC_Syntax_Syntax.binder_attrs = uu___5;_}::bs1 ->
             let uu___6 =
               let uu___7 =
                 let uu___8 =
                   let uu___9 =
                     FStarC_Syntax_Syntax.bv_to_name
                       a_b.FStarC_Syntax_Syntax.binder_bv in
                   (a, uu___9) in
                 FStarC_Syntax_Syntax.NT uu___8 in
               [uu___7] in
             FStarC_Syntax_Subst.subst_binders uu___6
               (FStar_Pervasives_Native.fst
                  (FStarC_List.splitAt
                     ((FStarC_List.length bs1) - (Prims.of_int 3)) bs1)))
    | uu___1 ->
        let uu___2 =
          let uu___3 =
            FStarC_Class_Show.show FStarC_Syntax_Print.showable_term ite_ty in
          FStarC_Format.fmt2
            "Type of %s is not an arrow with >= 4 binders (%s)" ite_name
            uu___3 in
        FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
          FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
          (Obj.magic FStarC_Errors_Msg.is_error_message_string)
          (Obj.magic uu___2) in
  let uu___ =
    let uu___1 =
      let uu___2 = FStarC_TypeChecker_Env.push_binders env (a_b :: rest_bs) in
      let uu___3 =
        FStarC_Syntax_Syntax.bv_to_name a_b.FStarC_Syntax_Syntax.binder_bv in
      FStarC_TypeChecker_Util.fresh_effect_repr uu___2 r eff_name sig_ts
        (FStar_Pervasives_Native.Some repr_ts)
        (FStarC_Syntax_Syntax.U_name u) uu___3 in
    match uu___1 with
    | (repr, g) ->
        let uu___2 =
          let uu___3 =
            FStarC_Syntax_Syntax.gen_bv "f" FStar_Pervasives_Native.None repr in
          FStarC_Syntax_Syntax.mk_binder uu___3 in
        (uu___2, g) in
  match uu___ with
  | (f, guard_f) ->
      let uu___1 =
        let uu___2 =
          let uu___3 =
            FStarC_TypeChecker_Env.push_binders env (a_b :: rest_bs) in
          let uu___4 =
            FStarC_Syntax_Syntax.bv_to_name
              a_b.FStarC_Syntax_Syntax.binder_bv in
          FStarC_TypeChecker_Util.fresh_effect_repr uu___3 r eff_name sig_ts
            (FStar_Pervasives_Native.Some repr_ts)
            (FStarC_Syntax_Syntax.U_name u) uu___4 in
        match uu___2 with
        | (repr, g) ->
            let uu___3 =
              let uu___4 =
                FStarC_Syntax_Syntax.gen_bv "g" FStar_Pervasives_Native.None
                  repr in
              FStarC_Syntax_Syntax.mk_binder uu___4 in
            (uu___3, g) in
      (match uu___1 with
       | (g, guard_g) ->
           let p =
             let uu___2 =
               FStarC_Syntax_Syntax.gen_bv "p" FStar_Pervasives_Native.None
                 FStarC_Syntax_Util.t_bool in
             FStarC_Syntax_Syntax.mk_binder uu___2 in
           let uu___2 =
             let uu___3 =
               FStarC_TypeChecker_Env.push_binders env
                 (FStarC_List.op_At (a_b :: rest_bs) [p]) in
             let uu___4 =
               FStarC_Syntax_Syntax.bv_to_name
                 a_b.FStarC_Syntax_Syntax.binder_bv in
             FStarC_TypeChecker_Util.fresh_effect_repr uu___3 r eff_name
               sig_ts (FStar_Pervasives_Native.Some repr_ts)
               (FStarC_Syntax_Syntax.U_name u) uu___4 in
           (match uu___2 with
            | (body_tm, guard_body) ->
                let k =
                  FStarC_Syntax_Util.abs
                    (FStarC_List.op_At (a_b :: rest_bs) [f; g; p]) body_tm
                    FStar_Pervasives_Native.None in
                let guard_eq =
                  let uu___3 = FStarC_TypeChecker_Rel.teq_nosmt env ite_tm k in
                  match uu___3 with
                  | FStar_Pervasives_Native.None ->
                      let uu___4 =
                        let uu___5 =
                          FStarC_Class_Show.show
                            FStarC_Syntax_Print.showable_term ite_tm in
                        FStarC_Format.fmt2 "Unexpected term for %s (%s)\n"
                          ite_name uu___5 in
                      FStarC_Errors.raise_error
                        FStarC_Class_HasRange.hasRange_range r
                        FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
                        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                        (Obj.magic uu___4)
                  | FStar_Pervasives_Native.Some g1 -> g1 in
                ((let uu___4 =
                    FStarC_TypeChecker_Env.conj_guards
                      [guard_f; guard_g; guard_body; guard_eq] in
                  FStarC_TypeChecker_Rel.force_trivial_guard env uu___4);
                 (let k1 =
                    let uu___4 =
                      FStarC_TypeChecker_Normalize.remove_uvar_solutions env
                        k in
                    FStarC_Syntax_Subst.compress uu___4 in
                  let kopt =
                    ite_combinator_kind env eff_name sig_ts repr_ts u k1
                      num_effect_params in
                  let kind =
                    match kopt with
                    | FStar_Pervasives_Native.None ->
                        (log_ad_hoc_combinator_warning ite_name r;
                         FStarC_Syntax_Syntax.Ad_hoc_combinator)
                    | FStar_Pervasives_Native.Some k2 -> k2 in
                  (let uu___5 =
                     let uu___6 = FStarC_Debug.medium () in
                     if uu___6
                     then true
                     else FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
                   if uu___5
                   then
                     let uu___6 =
                       FStarC_Class_Show.show
                         FStarC_Syntax_Syntax.showable_indexed_effect_combinator_kind
                         kind in
                     FStarC_Format.print2 "Ite %s has %s kind\n" ite_name
                       uu___6
                   else ());
                  (k1, kind)))))
let validate_indexed_effect_close_shape (env : FStarC_TypeChecker_Env.env)
  (eff_name : FStarC_Ident.lident) (sig_ts : FStarC_Syntax_Syntax.tscheme)
  (repr_ts : FStarC_Syntax_Syntax.tscheme)
  (u_a : FStarC_Syntax_Syntax.univ_name)
  (u_b : FStarC_Syntax_Syntax.univ_name)
  (close_tm : FStarC_Syntax_Syntax.term) (num_effect_params : Prims.int)
  (r : FStarC_Range_Type.t) : FStarC_Syntax_Syntax.term=
  let close_name =
    FStarC_Format.fmt1 "close_%s" (FStarC_Ident.string_of_lid eff_name) in
  let b_b =
    let uu___ =
      let uu___1 =
        FStarC_Syntax_Util.type_with_u (FStarC_Syntax_Syntax.U_name u_b) in
      FStarC_Syntax_Syntax.gen_bv "b" FStar_Pervasives_Native.None uu___1 in
    FStarC_Syntax_Syntax.mk_binder uu___ in
  let uu___ =
    let uu___1 =
      let uu___2 =
        let uu___3 =
          FStarC_TypeChecker_Env.inst_tscheme_with sig_ts
            [FStarC_Syntax_Syntax.U_name u_a] in
        FStar_Pervasives_Native.snd uu___3 in
      FStarC_Syntax_Util.arrow_formals uu___2 in
    FStar_Pervasives_Native.fst uu___1 in
  match uu___ with
  | a_b::sig_bs ->
      let uu___1 = FStarC_List.splitAt num_effect_params sig_bs in
      (match uu___1 with
       | (eff_params_bs, sig_bs1) ->
           let bs =
             FStarC_List.map
               (fun b ->
                  let x_b =
                    let uu___2 =
                      let uu___3 =
                        FStarC_Syntax_Syntax.bv_to_name
                          b_b.FStarC_Syntax_Syntax.binder_bv in
                      FStarC_Syntax_Syntax.gen_bv "x"
                        FStar_Pervasives_Native.None uu___3 in
                    FStarC_Syntax_Syntax.mk_binder uu___2 in
                  let uu___2 =
                    let uu___3 = b.FStarC_Syntax_Syntax.binder_bv in
                    let uu___4 =
                      let uu___5 =
                        FStarC_Syntax_Syntax.mk_Total
                          (b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort in
                      FStarC_Syntax_Util.arrow [x_b] uu___5 in
                    {
                      FStarC_Syntax_Syntax.ppname =
                        (uu___3.FStarC_Syntax_Syntax.ppname);
                      FStarC_Syntax_Syntax.index =
                        (uu___3.FStarC_Syntax_Syntax.index);
                      FStarC_Syntax_Syntax.sort = uu___4
                    } in
                  {
                    FStarC_Syntax_Syntax.binder_bv = uu___2;
                    FStarC_Syntax_Syntax.binder_qual =
                      (b.FStarC_Syntax_Syntax.binder_qual);
                    FStarC_Syntax_Syntax.binder_positivity =
                      (b.FStarC_Syntax_Syntax.binder_positivity);
                    FStarC_Syntax_Syntax.binder_attrs =
                      (b.FStarC_Syntax_Syntax.binder_attrs)
                  }) sig_bs1 in
           let f_b =
             let uu___2 =
               FStarC_TypeChecker_Env.inst_tscheme_with repr_ts
                 [FStarC_Syntax_Syntax.U_name u_a] in
             match uu___2 with
             | (uu___3, repr_t) ->
                 let x_b =
                   let uu___4 =
                     let uu___5 =
                       FStarC_Syntax_Syntax.bv_to_name
                         b_b.FStarC_Syntax_Syntax.binder_bv in
                     FStarC_Syntax_Syntax.gen_bv "x"
                       FStar_Pervasives_Native.None uu___5 in
                   FStarC_Syntax_Syntax.mk_binder uu___4 in
                 let is_args =
                   FStarC_List.map
                     (fun uu___4 ->
                        match uu___4 with
                        | { FStarC_Syntax_Syntax.binder_bv = binder_bv;
                            FStarC_Syntax_Syntax.binder_qual = uu___5;
                            FStarC_Syntax_Syntax.binder_positivity = uu___6;
                            FStarC_Syntax_Syntax.binder_attrs = uu___7;_} ->
                            let uu___8 =
                              let uu___9 =
                                FStarC_Syntax_Syntax.bv_to_name binder_bv in
                              let uu___10 =
                                let uu___11 =
                                  let uu___12 =
                                    FStarC_Syntax_Syntax.bv_to_name
                                      x_b.FStarC_Syntax_Syntax.binder_bv in
                                  FStarC_Syntax_Syntax.as_arg uu___12 in
                                [uu___11] in
                              FStarC_Syntax_Syntax.mk_Tm_app uu___9 uu___10
                                FStarC_Range_Type.dummyRange in
                            FStarC_Syntax_Syntax.as_arg uu___8) bs in
                 let repr_app =
                   let uu___4 =
                     let uu___5 =
                       let uu___6 =
                         FStarC_Syntax_Syntax.bv_to_name
                           a_b.FStarC_Syntax_Syntax.binder_bv in
                       FStarC_Syntax_Syntax.as_arg uu___6 in
                     uu___5 :: is_args in
                   FStarC_Syntax_Syntax.mk_Tm_app repr_t uu___4
                     FStarC_Range_Type.dummyRange in
                 let f_sort =
                   let uu___4 = FStarC_Syntax_Syntax.mk_Total repr_app in
                   FStarC_Syntax_Util.arrow [x_b] uu___4 in
                 let uu___4 =
                   FStarC_Syntax_Syntax.gen_bv "f"
                     FStar_Pervasives_Native.None f_sort in
                 FStarC_Syntax_Syntax.mk_binder uu___4 in
           let env1 =
             FStarC_TypeChecker_Env.push_binders env (a_b :: b_b ::
               (FStarC_List.op_At eff_params_bs bs)) in
           let uu___2 =
             let uu___3 =
               FStarC_Syntax_Syntax.bv_to_name
                 a_b.FStarC_Syntax_Syntax.binder_bv in
             FStarC_TypeChecker_Util.fresh_effect_repr env1 r eff_name sig_ts
               (FStar_Pervasives_Native.Some repr_ts)
               (FStarC_Syntax_Syntax.U_name u_a) uu___3 in
           (match uu___2 with
            | (body_tm, g_body) ->
                let k =
                  FStarC_Syntax_Util.abs (a_b :: b_b ::
                    (FStarC_List.op_At eff_params_bs
                       (FStarC_List.op_At bs [f_b]))) body_tm
                    FStar_Pervasives_Native.None in
                let g_eq =
                  let uu___3 =
                    FStarC_TypeChecker_Rel.teq_nosmt env1 close_tm k in
                  match uu___3 with
                  | FStar_Pervasives_Native.None ->
                      let uu___4 =
                        let uu___5 =
                          FStarC_Class_Show.show
                            FStarC_Syntax_Print.showable_term close_tm in
                        FStarC_Format.fmt2 "Unexpected term for %s (%s)\n"
                          close_name uu___5 in
                      FStarC_Errors.raise_error
                        FStarC_Class_HasRange.hasRange_range r
                        FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
                        (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                        (Obj.magic uu___4)
                  | FStar_Pervasives_Native.Some g -> g in
                ((let uu___4 = FStarC_TypeChecker_Env.conj_guard g_body g_eq in
                  FStarC_TypeChecker_Rel.force_trivial_guard env1 uu___4);
                 (let uu___4 =
                    FStarC_TypeChecker_Normalize.remove_uvar_solutions env1 k in
                  FStarC_Syntax_Subst.compress uu___4))))
let lift_combinator_kind (env : FStarC_TypeChecker_Env.env)
  (m_eff_name : FStarC_Ident.lident)
  (m_sig_ts : FStarC_Syntax_Syntax.tscheme)
  (m_repr_ts : FStarC_Syntax_Syntax.tscheme FStar_Pervasives_Native.option)
  (u : FStarC_Syntax_Syntax.univ_name) (k : FStarC_Syntax_Syntax.typ) :
  FStarC_Syntax_Syntax.indexed_effect_binder_kind Prims.list
    FStar_Pervasives_Native.option=
  let uu___ = FStarC_Syntax_Util.arrow_formals k in
  match uu___ with
  | (a_b::rest_bs, uu___1) ->
      let uu___2 =
        let f_sig_bs =
          let uu___3 =
            FStarC_TypeChecker_Env.inst_tscheme_with m_sig_ts
              [FStarC_Syntax_Syntax.U_name u] in
          match uu___3 with
          | (uu___4, sig1) ->
              let uu___5 =
                let uu___6 = FStarC_Syntax_Util.arrow_formals sig1 in
                FStar_Pervasives_Native.fst uu___6 in
              (match uu___5 with
               | a::bs ->
                   let uu___6 =
                     let uu___7 =
                       let uu___8 =
                         let uu___9 =
                           FStarC_Syntax_Syntax.bv_to_name
                             a_b.FStarC_Syntax_Syntax.binder_bv in
                         ((a.FStarC_Syntax_Syntax.binder_bv), uu___9) in
                       FStarC_Syntax_Syntax.NT uu___8 in
                     [uu___7] in
                   FStarC_Syntax_Subst.subst_binders uu___6 bs) in
        op_let_Question
          (if (FStarC_List.length rest_bs) < (FStarC_List.length f_sig_bs)
           then FStar_Pervasives_Native.None
           else
             FStar_Pervasives_Native.Some
               (FStarC_List.splitAt (FStarC_List.length f_sig_bs) rest_bs))
          (fun uu___3 ->
             match uu___3 with
             | (f_bs, rest_bs1) ->
                 let uu___4 = eq_binders env f_sig_bs f_bs in
                 op_let_Question uu___4
                   (fun f_bs_kinds ->
                      FStar_Pervasives_Native.Some
                        (f_bs, f_bs_kinds, rest_bs1))) in
      op_let_Question uu___2
        (fun uu___3 ->
           match uu___3 with
           | (f_bs, f_bs_kinds, rest_bs1) ->
               op_let_Question
                 (if Prims.uu___is_Cons rest_bs1
                  then
                    let uu___4 =
                      FStarC_List.splitAt
                        ((FStarC_List.length rest_bs1) - Prims.int_one)
                        rest_bs1 in
                    match uu___4 with
                    | (rest_bs2, f_b::[]) ->
                        FStar_Pervasives_Native.Some (rest_bs2, f_b)
                  else FStar_Pervasives_Native.None)
                 (fun uu___4 ->
                    match uu___4 with
                    | (rest_bs2, f_b) ->
                        let uu___5 =
                          let expected_f_b_sort =
                            match m_repr_ts with
                            | FStar_Pervasives_Native.Some repr_ts ->
                                let uu___6 =
                                  FStarC_TypeChecker_Env.inst_tscheme_with
                                    repr_ts [FStarC_Syntax_Syntax.U_name u] in
                                (match uu___6 with
                                 | (uu___7, t) ->
                                     let uu___8 =
                                       let uu___9 =
                                         let uu___10 =
                                           FStarC_Syntax_Syntax.bv_to_name
                                             a_b.FStarC_Syntax_Syntax.binder_bv in
                                         FStarC_Syntax_Syntax.as_arg uu___10 in
                                       let uu___10 =
                                         FStarC_List.map
                                           (fun uu___11 ->
                                              match uu___11 with
                                              | {
                                                  FStarC_Syntax_Syntax.binder_bv
                                                    = b;
                                                  FStarC_Syntax_Syntax.binder_qual
                                                    = uu___12;
                                                  FStarC_Syntax_Syntax.binder_positivity
                                                    = uu___13;
                                                  FStarC_Syntax_Syntax.binder_attrs
                                                    = uu___14;_}
                                                  ->
                                                  let uu___15 =
                                                    FStarC_Syntax_Syntax.bv_to_name
                                                      b in
                                                  FStarC_Syntax_Syntax.as_arg
                                                    uu___15) f_bs in
                                       uu___9 :: uu___10 in
                                     FStarC_Syntax_Syntax.mk_Tm_app t uu___8
                                       FStarC_Range_Type.dummyRange)
                            | FStar_Pervasives_Native.None ->
                                let uu___6 =
                                  let uu___7 =
                                    FStarC_Syntax_Syntax.null_binder
                                      FStarC_Syntax_Syntax.t_unit in
                                  [uu___7] in
                                let uu___7 =
                                  let uu___8 =
                                    let uu___9 =
                                      FStarC_Syntax_Syntax.bv_to_name
                                        a_b.FStarC_Syntax_Syntax.binder_bv in
                                    let uu___10 =
                                      FStarC_List.map
                                        (fun b ->
                                           let uu___11 =
                                             FStarC_Syntax_Syntax.bv_to_name
                                               b.FStarC_Syntax_Syntax.binder_bv in
                                           FStarC_Syntax_Syntax.as_arg
                                             uu___11) f_bs in
                                    {
                                      FStarC_Syntax_Syntax.comp_univs =
                                        [FStarC_Syntax_Syntax.U_name u];
                                      FStarC_Syntax_Syntax.effect_name =
                                        m_eff_name;
                                      FStarC_Syntax_Syntax.result_typ =
                                        uu___9;
                                      FStarC_Syntax_Syntax.effect_args =
                                        uu___10;
                                      FStarC_Syntax_Syntax.flags = []
                                    } in
                                  FStarC_Syntax_Syntax.mk_Comp uu___8 in
                                FStarC_Syntax_Util.arrow uu___6 uu___7 in
                          let uu___6 =
                            let uu___7 =
                              FStarC_TypeChecker_TermEqAndSimplify.eq_tm env
                                (f_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                                expected_f_b_sort in
                            uu___7 =
                              FStarC_TypeChecker_TermEqAndSimplify.Equal in
                          if uu___6
                          then FStar_Pervasives_Native.Some ()
                          else FStar_Pervasives_Native.None in
                        op_let_Question uu___5
                          (fun _f_b_ok_ ->
                             let rest_kinds =
                               FStarC_List.map
                                 (fun uu___6 ->
                                    FStarC_Syntax_Syntax.Ad_hoc_binder)
                                 rest_bs2 in
                             FStar_Pervasives_Native.Some
                               (FStarC_List.op_At
                                  [FStarC_Syntax_Syntax.Type_binder]
                                  (FStarC_List.op_At f_bs_kinds
                                     (FStarC_List.op_At rest_kinds
                                        [FStarC_Syntax_Syntax.Repr_binder]))))))
let validate_indexed_effect_lift_shape (env : FStarC_TypeChecker_Env.env)
  (m_eff_name : FStarC_Ident.lident) (n_eff_name : FStarC_Ident.lident)
  (u : FStarC_Syntax_Syntax.univ_name) (lift_t : FStarC_Syntax_Syntax.typ)
  (r : FStarC_Range_Type.t) :
  (FStarC_Syntax_Syntax.typ *
    FStarC_Syntax_Syntax.indexed_effect_combinator_kind)=
  let lift_name =
    FStarC_Format.fmt2 "%s ~> %s" (FStarC_Ident.string_of_lid m_eff_name)
      (FStarC_Ident.string_of_lid n_eff_name) in
  let lift_t_shape_error s =
    FStarC_Format.fmt2 "Unexpected shape of lift %s, reason:%s" lift_name s in
  let uu___ =
    let uu___1 = FStarC_TypeChecker_Env.get_effect_decl env m_eff_name in
    let uu___2 = FStarC_TypeChecker_Env.get_effect_decl env n_eff_name in
    (uu___1, uu___2) in
  match uu___ with
  | (m_ed, n_ed) ->
      let a_b =
        let uu___1 =
          let uu___2 =
            FStarC_Syntax_Util.type_with_u (FStarC_Syntax_Syntax.U_name u) in
          FStarC_Syntax_Syntax.gen_bv "a" FStar_Pervasives_Native.None uu___2 in
        FStarC_Syntax_Syntax.mk_binder uu___1 in
      let uu___1 =
        let uu___2 =
          let uu___3 = FStarC_Syntax_Subst.compress lift_t in
          uu___3.FStarC_Syntax_Syntax.n in
        match uu___2 with
        | FStarC_Syntax_Syntax.Tm_arrow
            { FStarC_Syntax_Syntax.bs1 = bs; FStarC_Syntax_Syntax.comp = c;_}
            when (FStarC_List.length bs) >= (Prims.of_int 2) ->
            let uu___3 = FStarC_Syntax_Subst.open_binders bs in
            (match uu___3 with
             | { FStarC_Syntax_Syntax.binder_bv = a;
                 FStarC_Syntax_Syntax.binder_qual = uu___4;
                 FStarC_Syntax_Syntax.binder_positivity = uu___5;
                 FStarC_Syntax_Syntax.binder_attrs = uu___6;_}::bs1 ->
                 let uu___7 =
                   let uu___8 =
                     let uu___9 =
                       let uu___10 =
                         let uu___11 =
                           FStarC_Syntax_Syntax.bv_to_name
                             a_b.FStarC_Syntax_Syntax.binder_bv in
                         (a, uu___11) in
                       FStarC_Syntax_Syntax.NT uu___10 in
                     [uu___9] in
                   FStarC_Syntax_Subst.subst_binders uu___8
                     (FStar_Pervasives_Native.fst
                        (FStarC_List.splitAt
                           ((FStarC_List.length bs1) - Prims.int_one) bs1)) in
                 let uu___8 =
                   FStarC_TypeChecker_Env.norm_eff_name env
                     (FStarC_Syntax_Util.comp_effect_name c) in
                 (uu___7, uu___8))
        | uu___3 ->
            FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
              FStarC_Errors_Codes.Fatal_UnexpectedExpressionType ()
              (Obj.magic FStarC_Errors_Msg.is_error_message_string)
              (Obj.magic
                 (lift_t_shape_error
                    "either not an arrow, or not enough binders")) in
      (match uu___1 with
       | (rest_bs, lift_eff) ->
           ((let uu___3 =
               let uu___4 =
                 if
                   FStarC_Ident.lid_equals lift_eff
                     FStarC_Parser_Const.effect_PURE_lid
                 then true
                 else
                   if
                     FStarC_Ident.lid_equals lift_eff
                       FStarC_Parser_Const.effect_GHOST_lid
                   then
                     FStarC_TypeChecker_Env.is_erasable_effect env m_eff_name
                   else false in
               Prims.op_Negation uu___4 in
             if uu___3
             then
               FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range
                 r FStarC_Errors_Codes.Fatal_UnexpectedExpressionType ()
                 (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                 (Obj.magic
                    (lift_t_shape_error
                       "the lift combinator has an unexpected effect: it must either be PURE or if the source effect is erasable then may be GHOST"))
             else ());
            (let uu___3 =
               let uu___4 =
                 let uu___5 =
                   FStarC_TypeChecker_Env.push_binders env (a_b :: rest_bs) in
                 let uu___6 =
                   FStarC_Syntax_Syntax.bv_to_name
                     a_b.FStarC_Syntax_Syntax.binder_bv in
                 FStarC_TypeChecker_Util.fresh_effect_repr uu___5 r
                   m_eff_name
                   (FStarC_Syntax_Util.effect_sig_ts
                      m_ed.FStarC_Syntax_Syntax.signature)
                   (FStarC_Syntax_Util.get_eff_repr m_ed)
                   (FStarC_Syntax_Syntax.U_name u) uu___6 in
               match uu___4 with
               | (repr, g) ->
                   let uu___5 =
                     let uu___6 =
                       FStarC_Syntax_Syntax.gen_bv "f"
                         FStar_Pervasives_Native.None repr in
                     FStarC_Syntax_Syntax.mk_binder uu___6 in
                   (uu___5, g) in
             match uu___3 with
             | (f, guard_f) ->
                 let uu___4 =
                   let uu___5 =
                     FStarC_TypeChecker_Env.push_binders env (a_b :: rest_bs) in
                   let uu___6 =
                     FStarC_Syntax_Syntax.bv_to_name
                       a_b.FStarC_Syntax_Syntax.binder_bv in
                   FStarC_TypeChecker_Util.fresh_effect_repr uu___5 r
                     n_eff_name
                     (FStarC_Syntax_Util.effect_sig_ts
                        n_ed.FStarC_Syntax_Syntax.signature)
                     (FStarC_Syntax_Util.get_eff_repr n_ed)
                     (FStarC_Syntax_Syntax.U_name u) uu___6 in
                 (match uu___4 with
                  | (ret_t, guard_ret_t) ->
                      let uu___5 =
                        let uu___6 =
                          FStarC_TypeChecker_Env.push_binders env (a_b ::
                            rest_bs) in
                        pure_wp_uvar uu___6 ret_t
                          (FStarC_Format.fmt1
                             "implicit for pure_wp in typechecking lift %s"
                             lift_name) r in
                      (match uu___5 with
                       | (pure_wp_uvar1, guard_wp) ->
                           let c =
                             let uu___6 =
                               let uu___7 =
                                 let uu___8 =
                                   FStarC_TypeChecker_Env.new_u_univ () in
                                 [uu___8] in
                               {
                                 FStarC_Syntax_Syntax.comp_univs = uu___7;
                                 FStarC_Syntax_Syntax.effect_name = lift_eff;
                                 FStarC_Syntax_Syntax.result_typ = ret_t;
                                 FStarC_Syntax_Syntax.effect_args =
                                   [FStarC_Syntax_Syntax.as_arg pure_wp_uvar1];
                                 FStarC_Syntax_Syntax.flags = []
                               } in
                             FStarC_Syntax_Syntax.mk_Comp uu___6 in
                           let k =
                             FStarC_Syntax_Util.arrow
                               (FStarC_List.op_At (a_b :: rest_bs) [f]) c in
                           let guard_eq =
                             let uu___6 =
                               FStarC_TypeChecker_Rel.teq_nosmt env lift_t k in
                             match uu___6 with
                             | FStar_Pervasives_Native.None ->
                                 let uu___7 =
                                   let uu___8 =
                                     FStarC_Class_Show.show
                                       FStarC_Syntax_Print.showable_term
                                       lift_t in
                                   FStarC_Format.fmt2
                                     "Unexpected type of %s (%s)\n" lift_name
                                     uu___8 in
                                 FStarC_Errors.raise_error
                                   FStarC_Class_HasRange.hasRange_range r
                                   FStarC_Errors_Codes.Fatal_UnexpectedEffect
                                   ()
                                   (Obj.magic
                                      FStarC_Errors_Msg.is_error_message_string)
                                   (Obj.magic uu___7)
                             | FStar_Pervasives_Native.Some g -> g in
                           ((let uu___7 =
                               FStarC_TypeChecker_Env.conj_guards
                                 [guard_f; guard_ret_t; guard_wp; guard_eq] in
                             FStarC_TypeChecker_Rel.force_trivial_guard env
                               uu___7);
                            (let k1 =
                               let uu___7 =
                                 FStarC_TypeChecker_Normalize.remove_uvar_solutions
                                   env k in
                               FStarC_Syntax_Subst.compress uu___7 in
                             let lopt =
                               lift_combinator_kind env m_eff_name
                                 (FStarC_Syntax_Util.effect_sig_ts
                                    m_ed.FStarC_Syntax_Syntax.signature)
                                 (FStarC_Syntax_Util.get_eff_repr m_ed) u k1 in
                             let kind =
                               match lopt with
                               | FStar_Pervasives_Native.None ->
                                   (log_ad_hoc_combinator_warning lift_name r;
                                    FStarC_Syntax_Syntax.Ad_hoc_combinator)
                               | FStar_Pervasives_Native.Some l ->
                                   FStarC_Syntax_Syntax.Substitutive_combinator
                                     l in
                             (let uu___8 =
                                let uu___9 = FStarC_Debug.medium () in
                                if uu___9
                                then true
                                else
                                  FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
                              if uu___8
                              then
                                let uu___9 =
                                  FStarC_Class_Show.show
                                    FStarC_Syntax_Syntax.showable_indexed_effect_combinator_kind
                                    kind in
                                FStarC_Format.print2 "Lift %s has %s kind\n"
                                  lift_name uu___9
                              else ());
                             (k1, kind))))))))
let tc_layered_eff_decl (env0 : FStarC_TypeChecker_Env.env)
  (ed : FStarC_Syntax_Syntax.eff_decl)
  (quals : FStarC_Syntax_Syntax.qualifier Prims.list)
  (attrs : FStarC_Syntax_Syntax.attribute Prims.list) :
  FStarC_Syntax_Syntax.eff_decl=
  FStarC_Errors.with_ctx
    (FStarC_Format.fmt1
       "While checking layered effect definition \226\128\152%s\226\128\153"
       (FStarC_Ident.string_of_lid ed.FStarC_Syntax_Syntax.mname))
    (fun uu___ ->
       (let uu___2 = FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
        if uu___2
        then
          let uu___3 =
            FStarC_Class_Show.show FStarC_Syntax_Print.showable_eff_decl ed in
          FStarC_Format.print1 "Typechecking layered effect: \n\t%s\n" uu___3
        else ());
       if
         ((FStarC_List.length ed.FStarC_Syntax_Syntax.univs) <>
            Prims.int_zero)
           ||
           ((FStarC_List.length ed.FStarC_Syntax_Syntax.binders) <>
              Prims.int_zero)
       then
         FStarC_Errors.raise_error FStarC_Ident.hasrange_lident
           ed.FStarC_Syntax_Syntax.mname
           FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
           (Obj.magic FStarC_Errors_Msg.is_error_message_string)
           (Obj.magic
              (Prims.strcat "Binders are not supported for layered effects ("
                 (Prims.strcat
                    (FStarC_Ident.string_of_lid ed.FStarC_Syntax_Syntax.mname)
                    ")")))
       else ();
       (let log_combinator s uu___3 =
          match uu___3 with
          | (us, t, ty) ->
              let uu___4 = FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
              if uu___4
              then
                let uu___5 = FStarC_Syntax_Print.tscheme_to_string (us, t) in
                let uu___6 = FStarC_Syntax_Print.tscheme_to_string (us, ty) in
                FStarC_Format.print4 "Typechecked %s:%s = %s:%s\n"
                  (FStarC_Ident.string_of_lid ed.FStarC_Syntax_Syntax.mname)
                  s uu___5 uu___6
              else () in
        let fresh_a_and_u_a a =
          let uu___3 = FStarC_Syntax_Util.type_u () in
          match uu___3 with
          | (t, u) ->
              let uu___4 =
                let uu___5 =
                  FStarC_Syntax_Syntax.gen_bv a FStar_Pervasives_Native.None
                    t in
                FStarC_Syntax_Syntax.mk_binder uu___5 in
              (uu___4, u) in
        let fresh_x_a x a =
          let uu___3 =
            let uu___4 =
              FStarC_Syntax_Syntax.bv_to_name
                a.FStarC_Syntax_Syntax.binder_bv in
            FStarC_Syntax_Syntax.gen_bv x FStar_Pervasives_Native.None uu___4 in
          FStarC_Syntax_Syntax.mk_binder uu___3 in
        let check_and_gen1 =
          check_and_gen env0
            (FStarC_Ident.string_of_lid ed.FStarC_Syntax_Syntax.mname) in
        let uu___3 =
          let uu___4 =
            match ed.FStarC_Syntax_Syntax.signature with
            | FStarC_Syntax_Syntax.Layered_eff_sig (n, ts) -> (n, ts)
            | uu___5 ->
                FStarC_Effect.failwith
                  "Impossible (tc_layered_eff_decl with a wp effect sig" in
          match uu___4 with
          | (n, sig_ts) ->
              FStarC_Errors.with_ctx "While checking the effect signature"
                (fun uu___5 ->
                   let r =
                     (FStar_Pervasives_Native.snd sig_ts).FStarC_Syntax_Syntax.pos in
                   let uu___6 =
                     check_and_gen1 "signature" Prims.int_one sig_ts in
                   match uu___6 with
                   | (sig_us, sig_t, sig_ty) ->
                       let uu___7 =
                         FStarC_Syntax_Subst.open_univ_vars sig_us sig_t in
                       (match uu___7 with
                        | (us, t) ->
                            let env =
                              FStarC_TypeChecker_Env.push_univ_vars env0 us in
                            let uu___8 = fresh_a_and_u_a "a" in
                            (match uu___8 with
                             | (a, u) ->
                                 let rest_bs =
                                   let uu___9 =
                                     FStarC_Syntax_Syntax.bv_to_name
                                       a.FStarC_Syntax_Syntax.binder_bv in
                                   FStarC_TypeChecker_Util.layered_effect_indices_as_binders
                                     env r ed.FStarC_Syntax_Syntax.mname
                                     (sig_us, sig_t) u uu___9 in
                                 let bs = a :: rest_bs in
                                 let k =
                                   let uu___9 =
                                     FStarC_Syntax_Syntax.mk_Total
                                       FStarC_Syntax_Syntax.teff in
                                   FStarC_Syntax_Util.arrow bs uu___9 in
                                 let g_eq =
                                   FStarC_TypeChecker_Rel.teq env t k in
                                 (FStarC_TypeChecker_Rel.force_trivial_guard
                                    env g_eq;
                                  (let uu___10 =
                                     let uu___11 =
                                       let uu___12 =
                                         FStarC_TypeChecker_Normalize.remove_uvar_solutions
                                           env k in
                                       FStarC_Syntax_Subst.close_univ_vars us
                                         uu___12 in
                                     (sig_us, uu___11, sig_ty) in
                                   (n, uu___10)))))) in
        match uu___3 with
        | (num_effect_params, signature) ->
            (log_combinator "signature" signature;
             (let repr =
                FStarC_Errors.with_ctx "While checking the effect repr"
                  (fun uu___5 ->
                     let repr_ts =
                       FStarC_Option.must
                         (FStarC_Syntax_Util.get_eff_repr ed) in
                     let r =
                       (FStar_Pervasives_Native.snd repr_ts).FStarC_Syntax_Syntax.pos in
                     let uu___6 = check_and_gen1 "repr" Prims.int_one repr_ts in
                     match uu___6 with
                     | (repr_us, repr_t, repr_ty) ->
                         let uu___7 =
                           FStarC_Syntax_Subst.open_univ_vars repr_us repr_ty in
                         (match uu___7 with
                          | (us, ty) ->
                              let env =
                                FStarC_TypeChecker_Env.push_univ_vars env0 us in
                              let uu___8 = fresh_a_and_u_a "a" in
                              (match uu___8 with
                               | (a, u) ->
                                   let rest_bs =
                                     let signature_ts =
                                       let uu___9 = signature in
                                       match uu___9 with
                                       | (us1, t, uu___10) -> (us1, t) in
                                     let uu___9 =
                                       FStarC_Syntax_Syntax.bv_to_name
                                         a.FStarC_Syntax_Syntax.binder_bv in
                                     FStarC_TypeChecker_Util.layered_effect_indices_as_binders
                                       env r ed.FStarC_Syntax_Syntax.mname
                                       signature_ts u uu___9 in
                                   let bs = a :: rest_bs in
                                   let k =
                                     let uu___9 =
                                       let uu___10 =
                                         FStarC_Syntax_Util.type_u () in
                                       match uu___10 with
                                       | (t, u1) ->
                                           FStarC_Syntax_Syntax.mk_Total t in
                                     FStarC_Syntax_Util.arrow bs uu___9 in
                                   let g =
                                     FStarC_TypeChecker_Rel.teq env ty k in
                                   (FStarC_TypeChecker_Rel.force_trivial_guard
                                      env g;
                                    (let uu___10 =
                                       let uu___11 =
                                         FStarC_TypeChecker_Normalize.remove_uvar_solutions
                                           env k in
                                       FStarC_Syntax_Subst.close_univ_vars us
                                         uu___11 in
                                     (repr_us, repr_t, uu___10)))))) in
              log_combinator "repr" repr;
              (let fresh_repr r env u a_tm =
                 let signature_ts =
                   let uu___6 = signature in
                   match uu___6 with | (us, t, uu___7) -> (us, t) in
                 let repr_ts =
                   let uu___6 = repr in
                   match uu___6 with | (us, t, uu___7) -> (us, t) in
                 FStarC_TypeChecker_Util.fresh_effect_repr env r
                   ed.FStarC_Syntax_Syntax.mname signature_ts
                   (FStar_Pervasives_Native.Some repr_ts) u a_tm in
               let not_an_arrow_error comb n t r =
                 let uu___6 =
                   let uu___7 =
                     FStarC_Class_Show.show FStarC_Class_Show.showable_int n in
                   let uu___8 =
                     FStarC_Class_Tagged.tag_of
                       FStarC_Syntax_Syntax.tagged_term t in
                   let uu___9 =
                     FStarC_Class_Show.show FStarC_Syntax_Print.showable_term
                       t in
                   FStarC_Format.fmt5
                     "Type of %s:%s is not an arrow with >= %s binders (%s::%s)"
                     (FStarC_Ident.string_of_lid
                        ed.FStarC_Syntax_Syntax.mname) comb uu___7 uu___8
                     uu___9 in
                 FStarC_Errors.raise_error
                   FStarC_Class_HasRange.hasRange_range r
                   FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
                   (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                   (Obj.magic uu___6) in
               let return_repr =
                 FStarC_Errors.with_ctx
                   "While checking the return combinator"
                   (fun uu___6 ->
                      let return_repr_ts =
                        FStarC_Option.must
                          (FStarC_Syntax_Util.get_return_repr ed) in
                      let r =
                        (FStar_Pervasives_Native.snd return_repr_ts).FStarC_Syntax_Syntax.pos in
                      let uu___7 =
                        check_and_gen1 "return_repr" Prims.int_one
                          return_repr_ts in
                      match uu___7 with
                      | (ret_us, ret_t, ret_ty) ->
                          let uu___8 =
                            FStarC_Syntax_Subst.open_univ_vars ret_us ret_ty in
                          (match uu___8 with
                           | (us, ty) ->
                               let env =
                                 FStarC_TypeChecker_Env.push_univ_vars env0
                                   us in
                               let uu___9 = fresh_a_and_u_a "a" in
                               (match uu___9 with
                                | (a, u_a) ->
                                    let x_a = fresh_x_a "x" a in
                                    let rest_bs =
                                      let uu___10 =
                                        let uu___11 =
                                          FStarC_Syntax_Subst.compress ty in
                                        uu___11.FStarC_Syntax_Syntax.n in
                                      match uu___10 with
                                      | FStarC_Syntax_Syntax.Tm_arrow
                                          { FStarC_Syntax_Syntax.bs1 = bs;
                                            FStarC_Syntax_Syntax.comp =
                                              uu___11;_}
                                          when
                                          (FStarC_List.length bs) >=
                                            (Prims.of_int 2)
                                          ->
                                          let uu___12 =
                                            FStarC_Syntax_Subst.open_binders
                                              bs in
                                          (match uu___12 with
                                           | {
                                               FStarC_Syntax_Syntax.binder_bv
                                                 = a';
                                               FStarC_Syntax_Syntax.binder_qual
                                                 = uu___13;
                                               FStarC_Syntax_Syntax.binder_positivity
                                                 = uu___14;
                                               FStarC_Syntax_Syntax.binder_attrs
                                                 = uu___15;_}::{
                                                                 FStarC_Syntax_Syntax.binder_bv
                                                                   = x';
                                                                 FStarC_Syntax_Syntax.binder_qual
                                                                   = uu___16;
                                                                 FStarC_Syntax_Syntax.binder_positivity
                                                                   = uu___17;
                                                                 FStarC_Syntax_Syntax.binder_attrs
                                                                   = uu___18;_}::bs1
                                               ->
                                               let uu___19 =
                                                 let uu___20 =
                                                   let uu___21 =
                                                     let uu___22 =
                                                       FStarC_Syntax_Syntax.bv_to_name
                                                         x_a.FStarC_Syntax_Syntax.binder_bv in
                                                     (x', uu___22) in
                                                   FStarC_Syntax_Syntax.NT
                                                     uu___21 in
                                                 [uu___20] in
                                               let uu___20 =
                                                 let uu___21 =
                                                   let uu___22 =
                                                     let uu___23 =
                                                       let uu___24 =
                                                         FStarC_Syntax_Syntax.bv_to_name
                                                           a.FStarC_Syntax_Syntax.binder_bv in
                                                       (a', uu___24) in
                                                     FStarC_Syntax_Syntax.NT
                                                       uu___23 in
                                                   [uu___22] in
                                                 FStarC_Syntax_Subst.subst_binders
                                                   uu___21 bs1 in
                                               FStarC_Syntax_Subst.subst_binders
                                                 uu___19 uu___20)
                                      | uu___11 ->
                                          not_an_arrow_error "return"
                                            (Prims.of_int 2) ty r in
                                    let bs = a :: x_a :: rest_bs in
                                    let uu___10 =
                                      let uu___11 =
                                        FStarC_TypeChecker_Env.push_binders
                                          env bs in
                                      let uu___12 =
                                        FStarC_Syntax_Syntax.bv_to_name
                                          a.FStarC_Syntax_Syntax.binder_bv in
                                      fresh_repr r uu___11 u_a uu___12 in
                                    (match uu___10 with
                                     | (repr1, g) ->
                                         let k =
                                           let uu___11 =
                                             FStarC_Syntax_Syntax.mk_Total
                                               repr1 in
                                           FStarC_Syntax_Util.arrow bs
                                             uu___11 in
                                         let g_eq =
                                           FStarC_TypeChecker_Rel.teq env ty
                                             k in
                                         ((let uu___12 =
                                             FStarC_TypeChecker_Env.conj_guard
                                               g g_eq in
                                           FStarC_TypeChecker_Rel.force_trivial_guard
                                             env uu___12);
                                          (let k1 =
                                             FStarC_TypeChecker_Normalize.remove_uvar_solutions
                                               env k in
                                           let uu___12 =
                                             FStarC_Syntax_Subst.close_univ_vars
                                               us k1 in
                                           (ret_us, ret_t, uu___12))))))) in
               log_combinator "return_repr" return_repr;
               (let uu___7 =
                  FStarC_Errors.with_ctx "While checking the bind combinator"
                    (fun uu___8 ->
                       let bind_repr_ts =
                         FStarC_Option.must
                           (FStarC_Syntax_Util.get_bind_repr ed) in
                       let r =
                         (FStar_Pervasives_Native.snd bind_repr_ts).FStarC_Syntax_Syntax.pos in
                       let uu___9 =
                         check_and_gen1 "bind_repr" (Prims.of_int 2)
                           bind_repr_ts in
                       match uu___9 with
                       | (bind_us, bind_t, bind_ty) ->
                           let uu___10 =
                             FStarC_Syntax_Subst.open_univ_vars bind_us
                               bind_ty in
                           (match uu___10 with
                            | (us, ty) ->
                                let env =
                                  FStarC_TypeChecker_Env.push_univ_vars env0
                                    us in
                                let uu___11 =
                                  let sig_ts =
                                    let uu___12 = signature in
                                    match uu___12 with
                                    | (us1, t, uu___13) -> (us1, t) in
                                  let repr_ts =
                                    let uu___12 = repr in
                                    match uu___12 with
                                    | (us1, t, uu___13) -> (us1, t) in
                                  let uu___12 =
                                    FStarC_Syntax_Util.has_attribute
                                      ed.FStarC_Syntax_Syntax.eff_attrs
                                      FStarC_Parser_Const.bind_has_range_args_attr in
                                  validate_indexed_effect_bind_shape env
                                    ed.FStarC_Syntax_Syntax.mname
                                    ed.FStarC_Syntax_Syntax.mname
                                    ed.FStarC_Syntax_Syntax.mname sig_ts
                                    sig_ts sig_ts
                                    (FStar_Pervasives_Native.Some repr_ts)
                                    (FStar_Pervasives_Native.Some repr_ts)
                                    (FStar_Pervasives_Native.Some repr_ts) us
                                    ty r num_effect_params uu___12 in
                                (match uu___11 with
                                 | (k, kind) ->
                                     let uu___12 =
                                       let uu___13 =
                                         FStarC_Syntax_Subst.close_univ_vars
                                           bind_us k in
                                       (bind_us, bind_t, uu___13) in
                                     (uu___12, kind)))) in
                match uu___7 with
                | (bind_repr, bind_kind) ->
                    (log_combinator "bind_repr" bind_repr;
                     (let uu___9 =
                        FStarC_Errors.with_ctx
                          "While checking the subcomp combinator"
                          (fun uu___10 ->
                             let stronger_repr =
                               let ts =
                                 FStarC_Option.must
                                   (FStarC_Syntax_Util.get_stronger_repr ed) in
                               let uu___11 =
                                 let uu___12 =
                                   FStarC_Syntax_Subst.compress
                                     (FStar_Pervasives_Native.snd ts) in
                                 uu___12.FStarC_Syntax_Syntax.n in
                               match uu___11 with
                               | FStarC_Syntax_Syntax.Tm_unknown ->
                                   let signature_ts =
                                     let uu___12 = signature in
                                     match uu___12 with
                                     | (us, t, uu___13) -> (us, t) in
                                   let uu___12 =
                                     FStarC_TypeChecker_Env.inst_tscheme_with
                                       signature_ts
                                       [FStarC_Syntax_Syntax.U_unknown] in
                                   (match uu___12 with
                                    | (uu___13, signature_t) ->
                                        let uu___14 =
                                          let uu___15 =
                                            FStarC_Syntax_Subst.compress
                                              signature_t in
                                          uu___15.FStarC_Syntax_Syntax.n in
                                        (match uu___14 with
                                         | FStarC_Syntax_Syntax.Tm_arrow
                                             { FStarC_Syntax_Syntax.bs1 = bs;
                                               FStarC_Syntax_Syntax.comp =
                                                 uu___15;_}
                                             ->
                                             let bs1 =
                                               FStarC_Syntax_Subst.open_binders
                                                 bs in
                                             let repr_t =
                                               let repr_ts =
                                                 let uu___16 = repr in
                                                 match uu___16 with
                                                 | (us, t, uu___17) ->
                                                     (us, t) in
                                               let uu___16 =
                                                 FStarC_TypeChecker_Env.inst_tscheme_with
                                                   repr_ts
                                                   [FStarC_Syntax_Syntax.U_unknown] in
                                               FStar_Pervasives_Native.snd
                                                 uu___16 in
                                             let repr_t_applied =
                                               let uu___16 =
                                                 let uu___17 =
                                                   let uu___18 =
                                                     let uu___19 =
                                                       let uu___20 =
                                                         FStarC_List.map
                                                           (fun b ->
                                                              b.FStarC_Syntax_Syntax.binder_bv)
                                                           bs1 in
                                                       FStarC_List.map
                                                         FStarC_Syntax_Syntax.bv_to_name
                                                         uu___20 in
                                                     FStarC_List.map
                                                       FStarC_Syntax_Syntax.as_arg
                                                       uu___19 in
                                                   {
                                                     FStarC_Syntax_Syntax.hd
                                                       = repr_t;
                                                     FStarC_Syntax_Syntax.args
                                                       = uu___18
                                                   } in
                                                 FStarC_Syntax_Syntax.Tm_app
                                                   uu___17 in
                                               FStarC_Syntax_Syntax.mk
                                                 uu___16
                                                 (FStarC_Ident.range_of_lid
                                                    ed.FStarC_Syntax_Syntax.mname) in
                                             let f_b =
                                               FStarC_Syntax_Syntax.null_binder
                                                 repr_t_applied in
                                             let uu___16 =
                                               let uu___17 =
                                                 let uu___18 =
                                                   FStarC_Syntax_Syntax.bv_to_name
                                                     f_b.FStarC_Syntax_Syntax.binder_bv in
                                                 FStarC_Syntax_Util.abs
                                                   (FStarC_List.op_At bs1
                                                      [f_b]) uu___18
                                                   FStar_Pervasives_Native.None in
                                               {
                                                 FStarC_Syntax_Syntax.n =
                                                   (uu___17.FStarC_Syntax_Syntax.n);
                                                 FStarC_Syntax_Syntax.pos =
                                                   (FStarC_Ident.range_of_lid
                                                      ed.FStarC_Syntax_Syntax.mname);
                                                 FStarC_Syntax_Syntax.vars =
                                                   (uu___17.FStarC_Syntax_Syntax.vars);
                                                 FStarC_Syntax_Syntax.hash_code
                                                   =
                                                   (uu___17.FStarC_Syntax_Syntax.hash_code)
                                               } in
                                             ([], uu___16)
                                         | uu___15 ->
                                             FStarC_Effect.failwith
                                               "Impossible!"))
                               | uu___12 -> ts in
                             let r =
                               (FStar_Pervasives_Native.snd stronger_repr).FStarC_Syntax_Syntax.pos in
                             let uu___11 =
                               check_and_gen1 "stronger_repr" Prims.int_one
                                 stronger_repr in
                             match uu___11 with
                             | (stronger_us, stronger_t, stronger_ty) ->
                                 ((let uu___13 =
                                     FStarC_Effect.op_Bang
                                       dbg_LayeredEffectsTc in
                                   if uu___13
                                   then
                                     let uu___14 =
                                       FStarC_Syntax_Print.tscheme_to_string
                                         (stronger_us, stronger_t) in
                                     let uu___15 =
                                       FStarC_Syntax_Print.tscheme_to_string
                                         (stronger_us, stronger_ty) in
                                     FStarC_Format.print2
                                       "stronger combinator typechecked with term: %s and type: %s\n"
                                       uu___14 uu___15
                                   else ());
                                  (let uu___13 =
                                     FStarC_Syntax_Subst.open_univ_vars
                                       stronger_us stronger_ty in
                                   match uu___13 with
                                   | (us, ty) ->
                                       let env =
                                         FStarC_TypeChecker_Env.push_univ_vars
                                           env0 us in
                                       let uu___14 =
                                         let sig_ts =
                                           let uu___15 = signature in
                                           match uu___15 with
                                           | (us1, t, uu___16) -> (us1, t) in
                                         let repr_ts =
                                           let uu___15 = repr in
                                           match uu___15 with
                                           | (us1, t, uu___16) -> (us1, t) in
                                         validate_indexed_effect_subcomp_shape
                                           env ed.FStarC_Syntax_Syntax.mname
                                           ed.FStarC_Syntax_Syntax.mname
                                           sig_ts sig_ts
                                           (FStar_Pervasives_Native.Some
                                              repr_ts)
                                           (FStar_Pervasives_Native.Some
                                              repr_ts) (FStarC_List.hd us) ty
                                           num_effect_params r in
                                       (match uu___14 with
                                        | (k, kind) ->
                                            let uu___15 =
                                              let uu___16 =
                                                FStarC_Syntax_Subst.close_univ_vars
                                                  stronger_us k in
                                              (stronger_us, stronger_t,
                                                uu___16) in
                                            (uu___15, kind))))) in
                      match uu___9 with
                      | (stronger_repr, subcomp_kind) ->
                          (log_combinator "stronger_repr" stronger_repr;
                           (let uu___11 =
                              FStarC_Errors.with_ctx
                                "While checking the if_then_else combinator"
                                (fun uu___12 ->
                                   let if_then_else_ts =
                                     let ts =
                                       let uu___13 =
                                         FStarC_Option.must
                                           (FStarC_Syntax_Util.get_layered_if_then_else_combinator
                                              ed) in
                                       FStar_Pervasives_Native.fst uu___13 in
                                     let uu___13 =
                                       let uu___14 =
                                         FStarC_Syntax_Subst.compress
                                           (FStar_Pervasives_Native.snd ts) in
                                       uu___14.FStarC_Syntax_Syntax.n in
                                     match uu___13 with
                                     | FStarC_Syntax_Syntax.Tm_unknown ->
                                         let signature_ts =
                                           let uu___14 = signature in
                                           match uu___14 with
                                           | (us, t, uu___15) -> (us, t) in
                                         let uu___14 =
                                           FStarC_TypeChecker_Env.inst_tscheme_with
                                             signature_ts
                                             [FStarC_Syntax_Syntax.U_unknown] in
                                         (match uu___14 with
                                          | (uu___15, signature_t) ->
                                              let uu___16 =
                                                let uu___17 =
                                                  FStarC_Syntax_Subst.compress
                                                    signature_t in
                                                uu___17.FStarC_Syntax_Syntax.n in
                                              (match uu___16 with
                                               | FStarC_Syntax_Syntax.Tm_arrow
                                                   {
                                                     FStarC_Syntax_Syntax.bs1
                                                       = bs;
                                                     FStarC_Syntax_Syntax.comp
                                                       = uu___17;_}
                                                   ->
                                                   let bs1 =
                                                     FStarC_Syntax_Subst.open_binders
                                                       bs in
                                                   let repr_t =
                                                     let repr_ts =
                                                       let uu___18 = repr in
                                                       match uu___18 with
                                                       | (us, t, uu___19) ->
                                                           (us, t) in
                                                     let uu___18 =
                                                       FStarC_TypeChecker_Env.inst_tscheme_with
                                                         repr_ts
                                                         [FStarC_Syntax_Syntax.U_unknown] in
                                                     FStar_Pervasives_Native.snd
                                                       uu___18 in
                                                   let repr_t_applied =
                                                     let uu___18 =
                                                       let uu___19 =
                                                         let uu___20 =
                                                           let uu___21 =
                                                             let uu___22 =
                                                               FStarC_List.map
                                                                 (fun b ->
                                                                    b.FStarC_Syntax_Syntax.binder_bv)
                                                                 bs1 in
                                                             FStarC_List.map
                                                               FStarC_Syntax_Syntax.bv_to_name
                                                               uu___22 in
                                                           FStarC_List.map
                                                             FStarC_Syntax_Syntax.as_arg
                                                             uu___21 in
                                                         {
                                                           FStarC_Syntax_Syntax.hd
                                                             = repr_t;
                                                           FStarC_Syntax_Syntax.args
                                                             = uu___20
                                                         } in
                                                       FStarC_Syntax_Syntax.Tm_app
                                                         uu___19 in
                                                     FStarC_Syntax_Syntax.mk
                                                       uu___18
                                                       (FStarC_Ident.range_of_lid
                                                          ed.FStarC_Syntax_Syntax.mname) in
                                                   let f_b =
                                                     FStarC_Syntax_Syntax.null_binder
                                                       repr_t_applied in
                                                   let g_b =
                                                     FStarC_Syntax_Syntax.null_binder
                                                       repr_t_applied in
                                                   let b_b =
                                                     FStarC_Syntax_Syntax.null_binder
                                                       FStarC_Syntax_Util.t_bool in
                                                   let uu___18 =
                                                     let uu___19 =
                                                       FStarC_Syntax_Util.abs
                                                         (FStarC_List.op_At
                                                            bs1
                                                            [f_b; g_b; b_b])
                                                         repr_t_applied
                                                         FStar_Pervasives_Native.None in
                                                     {
                                                       FStarC_Syntax_Syntax.n
                                                         =
                                                         (uu___19.FStarC_Syntax_Syntax.n);
                                                       FStarC_Syntax_Syntax.pos
                                                         =
                                                         (FStarC_Ident.range_of_lid
                                                            ed.FStarC_Syntax_Syntax.mname);
                                                       FStarC_Syntax_Syntax.vars
                                                         =
                                                         (uu___19.FStarC_Syntax_Syntax.vars);
                                                       FStarC_Syntax_Syntax.hash_code
                                                         =
                                                         (uu___19.FStarC_Syntax_Syntax.hash_code)
                                                     } in
                                                   ([], uu___18)
                                               | uu___17 ->
                                                   FStarC_Effect.failwith
                                                     "Impossible!"))
                                     | uu___14 -> ts in
                                   let r =
                                     (FStar_Pervasives_Native.snd
                                        if_then_else_ts).FStarC_Syntax_Syntax.pos in
                                   let uu___13 =
                                     check_and_gen1 "if_then_else"
                                       Prims.int_one if_then_else_ts in
                                   match uu___13 with
                                   | (if_then_else_us, if_then_else_t,
                                      if_then_else_ty) ->
                                       let uu___14 =
                                         FStarC_Syntax_Subst.open_univ_vars
                                           if_then_else_us if_then_else_t in
                                       (match uu___14 with
                                        | (us, t) ->
                                            let uu___15 =
                                              FStarC_Syntax_Subst.open_univ_vars
                                                if_then_else_us
                                                if_then_else_ty in
                                            (match uu___15 with
                                             | (uu___16, ty) ->
                                                 let env =
                                                   FStarC_TypeChecker_Env.push_univ_vars
                                                     env0 us in
                                                 let uu___17 =
                                                   let sig_ts =
                                                     let uu___18 = signature in
                                                     match uu___18 with
                                                     | (us1, t1, uu___19) ->
                                                         (us1, t1) in
                                                   let repr_ts =
                                                     let uu___18 = repr in
                                                     match uu___18 with
                                                     | (us1, t1, uu___19) ->
                                                         (us1, t1) in
                                                   validate_indexed_effect_ite_shape
                                                     env
                                                     ed.FStarC_Syntax_Syntax.mname
                                                     sig_ts repr_ts
                                                     (FStarC_List.hd us) ty t
                                                     num_effect_params r in
                                                 (match uu___17 with
                                                  | (k, kind) ->
                                                      let uu___18 =
                                                        let uu___19 =
                                                          FStarC_Syntax_Subst.close_univ_vars
                                                            if_then_else_us k in
                                                        (if_then_else_us,
                                                          uu___19,
                                                          if_then_else_ty) in
                                                      (uu___18, kind))))) in
                            match uu___11 with
                            | (if_then_else, ite_kind) ->
                                (log_combinator "if_then_else" if_then_else;
                                 FStarC_Errors.with_ctx
                                   "While checking if-then-else soundness"
                                   (fun uu___13 ->
                                      let r =
                                        let uu___14 =
                                          let uu___15 =
                                            let uu___16 =
                                              FStarC_Option.must
                                                (FStarC_Syntax_Util.get_layered_if_then_else_combinator
                                                   ed) in
                                            FStar_Pervasives_Native.fst
                                              uu___16 in
                                          FStar_Pervasives_Native.snd uu___15 in
                                        uu___14.FStarC_Syntax_Syntax.pos in
                                      let uu___14 = if_then_else in
                                      match uu___14 with
                                      | (ite_us, ite_t, uu___15) ->
                                          let uu___16 =
                                            FStarC_Syntax_Subst.open_univ_vars
                                              ite_us ite_t in
                                          (match uu___16 with
                                           | (us, ite_t1) ->
                                               let uu___17 =
                                                 let uu___18 =
                                                   let uu___19 =
                                                     FStarC_Syntax_Subst.compress
                                                       ite_t1 in
                                                   uu___19.FStarC_Syntax_Syntax.n in
                                                 match uu___18 with
                                                 | FStarC_Syntax_Syntax.Tm_abs
                                                     {
                                                       FStarC_Syntax_Syntax.bs
                                                         = bs;
                                                       FStarC_Syntax_Syntax.body
                                                         = uu___19;
                                                       FStarC_Syntax_Syntax.rc_opt
                                                         = uu___20;_}
                                                     ->
                                                     let bs1 =
                                                       FStarC_Syntax_Subst.open_binders
                                                         bs in
                                                     let uu___21 =
                                                       let uu___22 =
                                                         FStar_Pervasives_Native.snd
                                                           (FStarC_List.splitAt
                                                              ((FStarC_List.length
                                                                  bs1)
                                                                 -
                                                                 (Prims.of_int
                                                                    3)) bs1) in
                                                       match uu___22 with
                                                       | f::g::p::[] ->
                                                           (f, g, p) in
                                                     (match uu___21 with
                                                      | (f_b, g_b, p_b) ->
                                                          let env =
                                                            let uu___22 =
                                                              FStarC_TypeChecker_Env.push_univ_vars
                                                                env0 us in
                                                            FStarC_TypeChecker_Env.push_binders
                                                              uu___22 bs1 in
                                                          let uu___22 =
                                                            let uu___23 =
                                                              let uu___24 =
                                                                FStarC_List.map
                                                                  (fun b ->
                                                                    let uu___25
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b.FStarC_Syntax_Syntax.binder_bv in
                                                                    (uu___25,
                                                                    (FStarC_Syntax_Util.aqual_of_binder
                                                                    b))) bs1 in
                                                              FStarC_Syntax_Syntax.mk_Tm_app
                                                                ite_t1
                                                                uu___24 r in
                                                            FStarC_TypeChecker_Normalize.normalize
                                                              [FStarC_TypeChecker_Env.Beta]
                                                              env uu___23 in
                                                          let uu___23 =
                                                            FStarC_Syntax_Syntax.bv_to_name
                                                              p_b.FStarC_Syntax_Syntax.binder_bv in
                                                          (env, uu___22,
                                                            (FStarC_List.hd
                                                               bs1), f_b,
                                                            g_b, uu___23))
                                                 | uu___19 ->
                                                     FStarC_Effect.failwith
                                                       "Impossible! ite_t must have been an abstraction with at least 3 binders" in
                                               (match uu___17 with
                                                | (env, ite_t_applied, a_b,
                                                   f_b, g_b, p_t) ->
                                                    let uu___18 =
                                                      let uu___19 =
                                                        stronger_repr in
                                                      match uu___19 with
                                                      | (uu___20, uu___21,
                                                         subcomp_ty) ->
                                                          let uu___22 =
                                                            FStarC_Syntax_Subst.open_univ_vars
                                                              us subcomp_ty in
                                                          (match uu___22 with
                                                           | (uu___23,
                                                              subcomp_ty1) ->
                                                               let uu___24 =
                                                                 let uu___25
                                                                   =
                                                                   FStarC_Syntax_Subst.compress
                                                                    subcomp_ty1 in
                                                                 uu___25.FStarC_Syntax_Syntax.n in
                                                               (match uu___24
                                                                with
                                                                | FStarC_Syntax_Syntax.Tm_arrow
                                                                    {
                                                                    FStarC_Syntax_Syntax.bs1
                                                                    = bs;
                                                                    FStarC_Syntax_Syntax.comp
                                                                    = c;_} ->
                                                                    let uu___25
                                                                    =
                                                                    FStarC_Syntax_Subst.open_comp
                                                                    bs c in
                                                                    (match uu___25
                                                                    with
                                                                    | 
                                                                    (bs1, c1)
                                                                    ->
                                                                    let uu___26
                                                                    =
                                                                    ((FStarC_List.hd
                                                                    bs1),
                                                                    (FStarC_List.tl
                                                                    bs1)) in
                                                                    (match uu___26
                                                                    with
                                                                    | 
                                                                    (a_b1,
                                                                    rest_bs)
                                                                    ->
                                                                    let uu___27
                                                                    =
                                                                    match 
                                                                    FStarC_List.splitAt
                                                                    ((FStarC_List.length
                                                                    rest_bs)
                                                                    -
                                                                    Prims.int_one)
                                                                    rest_bs
                                                                    with
                                                                    | 
                                                                    (l1, l2)
                                                                    ->
                                                                    (l1,
                                                                    (FStarC_List.hd
                                                                    l2)) in
                                                                    (match uu___27
                                                                    with
                                                                    | 
                                                                    (rest_bs1,
                                                                    f_b1) ->
                                                                    (a_b1,
                                                                    rest_bs1,
                                                                    f_b1, c1))))
                                                                | uu___25 ->
                                                                    FStarC_Effect.failwith
                                                                    "Impossible! subcomp_ty must have been an arrow with at lease 1 binder")) in
                                                    (match uu___18 with
                                                     | (subcomp_a_b,
                                                        subcomp_bs,
                                                        subcomp_f_b,
                                                        subcomp_c) ->
                                                         let check_branch
                                                           env1
                                                           ite_f_or_g_sort
                                                           attr_opt =
                                                           let uu___19 =
                                                             let uu___20 =
                                                               let uu___21 =
                                                                 let uu___22
                                                                   =
                                                                   let uu___23
                                                                    =
                                                                    let uu___24
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    a_b.FStarC_Syntax_Syntax.binder_bv in
                                                                    ((subcomp_a_b.FStarC_Syntax_Syntax.binder_bv),
                                                                    uu___24) in
                                                                   FStarC_Syntax_Syntax.NT
                                                                    uu___23 in
                                                                 [uu___22] in
                                                               (uu___21, [],
                                                                 FStarC_TypeChecker_Env.trivial_guard) in
                                                             FStarC_List.fold_left
                                                               (fun uu___21 b
                                                                  ->
                                                                  match uu___21
                                                                  with
                                                                  | (subst,
                                                                    uvars, g)
                                                                    ->
                                                                    let sort
                                                                    =
                                                                    FStarC_Syntax_Subst.subst
                                                                    subst
                                                                    (b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort in
                                                                    let uu___22
                                                                    =
                                                                    let ctx_uvar_meta
                                                                    =
                                                                    FStarC_Option.map
                                                                    (fun
                                                                    uu___23
                                                                    ->
                                                                    FStarC_Syntax_Syntax.Ctx_uvar_meta_attr
                                                                    uu___23)
                                                                    attr_opt in
                                                                    let uu___23
                                                                    =
                                                                    let uu___24
                                                                    =
                                                                    FStarC_Class_Show.show
                                                                    FStarC_Syntax_Print.showable_binder
                                                                    b in
                                                                    FStarC_Format.fmt1
                                                                    "uvar for subcomp %s binder when checking ite soundness"
                                                                    uu___24 in
                                                                    FStarC_TypeChecker_Env.new_implicit_var_aux
                                                                    uu___23 r
                                                                    env1 sort
                                                                    FStarC_Syntax_Syntax.Strict
                                                                    ctx_uvar_meta
                                                                    false in
                                                                    (match uu___22
                                                                    with
                                                                    | 
                                                                    (t,
                                                                    uu___23,
                                                                    g_t) ->
                                                                    let uu___24
                                                                    =
                                                                    FStarC_TypeChecker_Common.conj_guard
                                                                    g g_t in
                                                                    ((FStarC_List.op_At
                                                                    subst
                                                                    [
                                                                    FStarC_Syntax_Syntax.NT
                                                                    ((b.FStarC_Syntax_Syntax.binder_bv),
                                                                    t)]),
                                                                    (FStarC_List.op_At
                                                                    uvars 
                                                                    [t]),
                                                                    uu___24)))
                                                               uu___20
                                                               subcomp_bs in
                                                           match uu___19 with
                                                           | (subst, uvars,
                                                              g_uvars) ->
                                                               let subcomp_f_sort
                                                                 =
                                                                 FStarC_Syntax_Subst.subst
                                                                   subst
                                                                   (subcomp_f_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort in
                                                               let c =
                                                                 let uu___20
                                                                   =
                                                                   FStarC_Syntax_Subst.subst_comp
                                                                    subst
                                                                    subcomp_c in
                                                                 FStarC_TypeChecker_Env.unfold_effect_abbrev
                                                                   env1
                                                                   uu___20 in
                                                               let g_f_or_g =
                                                                 FStarC_TypeChecker_Rel.layered_effect_teq
                                                                   env1
                                                                   subcomp_f_sort
                                                                   ite_f_or_g_sort
                                                                   FStar_Pervasives_Native.None in
                                                               let g_c =
                                                                 FStarC_TypeChecker_Rel.layered_effect_teq
                                                                   env1
                                                                   c.FStarC_Syntax_Syntax.result_typ
                                                                   ite_t_applied
                                                                   FStar_Pervasives_Native.None in
                                                               let fml =
                                                                 FStarC_TypeChecker_Env.pure_precondition_for_trivial_post
                                                                   env1
                                                                   (FStarC_List.hd
                                                                    c.FStarC_Syntax_Syntax.comp_univs)
                                                                   c.FStarC_Syntax_Syntax.result_typ
                                                                   (FStar_Pervasives_Native.fst
                                                                    (FStarC_List.hd
                                                                    c.FStarC_Syntax_Syntax.effect_args))
                                                                   r in
                                                               let g_precondition
                                                                 =
                                                                 match attr_opt
                                                                 with
                                                                 | FStar_Pervasives_Native.None
                                                                    ->
                                                                    FStarC_TypeChecker_Env.guard_of_guard_formula
                                                                    (FStarC_TypeChecker_Common.NonTrivial
                                                                    fml)
                                                                 | FStar_Pervasives_Native.Some
                                                                    attr ->
                                                                    let uu___20
                                                                    =
                                                                    let uu___21
                                                                    =
                                                                    FStarC_Syntax_Util.mk_squash
                                                                    fml in
                                                                    FStarC_TypeChecker_Env.new_implicit_var_aux
                                                                    "tc_layered_effect_decl.g_precondition"
                                                                    r env1
                                                                    uu___21
                                                                    FStarC_Syntax_Syntax.Strict
                                                                    (FStar_Pervasives_Native.Some
                                                                    (FStarC_Syntax_Syntax.Ctx_uvar_meta_attr
                                                                    attr))
                                                                    false in
                                                                    (match uu___20
                                                                    with
                                                                    | 
                                                                    (uu___21,
                                                                    uu___22,
                                                                    g) -> g) in
                                                               let uu___20 =
                                                                 FStarC_TypeChecker_Env.conj_guards
                                                                   [g_uvars;
                                                                   g_f_or_g;
                                                                   g_c;
                                                                   g_precondition] in
                                                               FStarC_TypeChecker_Rel.force_trivial_guard
                                                                 env1 uu___20 in
                                                         let ite_soundness_tac_attr
                                                           =
                                                           let uu___19 =
                                                             FStarC_Syntax_Util.get_attribute
                                                               FStarC_Parser_Const.ite_soundness_by_attr
                                                               attrs in
                                                           match uu___19 with
                                                           | FStar_Pervasives_Native.Some
                                                               ((t, uu___20)::uu___21)
                                                               ->
                                                               FStar_Pervasives_Native.Some
                                                                 t
                                                           | uu___20 ->
                                                               FStar_Pervasives_Native.None in
                                                         ((let env1 =
                                                             let uu___19 =
                                                               let uu___20 =
                                                                 let uu___21
                                                                   =
                                                                   FStarC_Syntax_Util.b2t
                                                                    p_t in
                                                                 FStarC_Syntax_Util.mk_squash
                                                                   uu___21 in
                                                               FStarC_Syntax_Syntax.new_bv
                                                                 FStar_Pervasives_Native.None
                                                                 uu___20 in
                                                             FStarC_TypeChecker_Env.push_bv
                                                               env uu___19 in
                                                           check_branch env1
                                                             (f_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                                                             ite_soundness_tac_attr);
                                                          (let not_p =
                                                             let uu___19 =
                                                               FStarC_Syntax_Syntax.fv_to_tm
                                                                 (FStarC_Syntax_Syntax.lid_as_fv
                                                                    FStarC_Parser_Const.not_lid
                                                                    FStar_Pervasives_Native.None) in
                                                             let uu___20 =
                                                               let uu___21 =
                                                                 let uu___22
                                                                   =
                                                                   FStarC_Syntax_Util.b2t
                                                                    p_t in
                                                                 FStarC_Syntax_Syntax.as_arg
                                                                   uu___22 in
                                                               [uu___21] in
                                                             FStarC_Syntax_Syntax.mk_Tm_app
                                                               uu___19
                                                               uu___20 r in
                                                           let env1 =
                                                             let uu___19 =
                                                               FStarC_Syntax_Syntax.new_bv
                                                                 FStar_Pervasives_Native.None
                                                                 not_p in
                                                             FStarC_TypeChecker_Env.push_bv
                                                               env uu___19 in
                                                           check_branch env1
                                                             (g_b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                                                             ite_soundness_tac_attr))))));
                                 (let close_ =
                                    FStarC_Errors.with_ctx
                                      "While checking the close combinator"
                                      (fun uu___13 ->
                                         let ts_opt =
                                           FStarC_Syntax_Util.get_layered_close_combinator
                                             ed in
                                         match ts_opt with
                                         | FStar_Pervasives_Native.None ->
                                             FStar_Pervasives_Native.None
                                         | FStar_Pervasives_Native.Some
                                             close_ts ->
                                             let r =
                                               (FStar_Pervasives_Native.snd
                                                  close_ts).FStarC_Syntax_Syntax.pos in
                                             let uu___14 =
                                               check_and_gen1 "close"
                                                 (Prims.of_int 2) close_ts in
                                             (match uu___14 with
                                              | (close_us, close_t, close_ty)
                                                  ->
                                                  let uu___15 =
                                                    FStarC_Syntax_Subst.open_univ_vars
                                                      close_us close_t in
                                                  (match uu___15 with
                                                   | (us, t) ->
                                                       let env =
                                                         FStarC_TypeChecker_Env.push_univ_vars
                                                           env0 us in
                                                       let k =
                                                         let sig_ts =
                                                           let uu___16 =
                                                             signature in
                                                           match uu___16 with
                                                           | (us1, t1,
                                                              uu___17) ->
                                                               (us1, t1) in
                                                         let repr_ts =
                                                           let uu___16 = repr in
                                                           match uu___16 with
                                                           | (us1, t1,
                                                              uu___17) ->
                                                               (us1, t1) in
                                                         let uu___16 = us in
                                                         match uu___16 with
                                                         | u_a::u_b::[] ->
                                                             validate_indexed_effect_close_shape
                                                               env
                                                               ed.FStarC_Syntax_Syntax.mname
                                                               sig_ts repr_ts
                                                               u_a u_b t
                                                               num_effect_params
                                                               r in
                                                       let uu___16 =
                                                         let uu___17 =
                                                           FStarC_Syntax_Subst.close_univ_vars
                                                             close_us k in
                                                         (close_us, uu___17,
                                                           close_ty) in
                                                       FStar_Pervasives_Native.Some
                                                         uu___16))) in
                                  FStarC_Errors.with_ctx
                                    "While checking the soundness of the close combinator"
                                    (fun uu___13 ->
                                       match close_ with
                                       | FStar_Pervasives_Native.None -> ()
                                       | FStar_Pervasives_Native.Some close_1
                                           ->
                                           let uu___14 = close_1 in
                                           (match uu___14 with
                                            | (us, close_tm, uu___15) ->
                                                let r =
                                                  close_tm.FStarC_Syntax_Syntax.pos in
                                                ((let supported_subcomp =
                                                    match subcomp_kind with
                                                    | FStarC_Syntax_Syntax.Substitutive_combinator
                                                        l ->
                                                        Prims.op_Negation
                                                          (FStarC_List.contains
                                                             FStarC_Syntax_Syntax.Ad_hoc_binder
                                                             l)
                                                    | uu___17 -> false in
                                                  if
                                                    Prims.op_Negation
                                                      supported_subcomp
                                                  then
                                                    FStarC_Errors.raise_error
                                                      FStarC_Class_HasRange.hasRange_range
                                                      r
                                                      FStarC_Errors_Codes.Fatal_UnexpectedEffect
                                                      ()
                                                      (Obj.magic
                                                         FStarC_Errors_Msg.is_error_message_string)
                                                      (Obj.magic
                                                         "close combinator is only allowed for effects with substitutive subcomp")
                                                  else ());
                                                 (let uu___17 =
                                                    FStarC_Syntax_Subst.open_univ_vars
                                                      us close_tm in
                                                  match uu___17 with
                                                  | (us1, close_tm1) ->
                                                      let env01 =
                                                        FStarC_TypeChecker_Env.push_univ_vars
                                                          env0 us1 in
                                                      let uu___18 =
                                                        FStarC_Syntax_Util.abs_formals
                                                          close_tm1 in
                                                      (match uu___18 with
                                                       | (close_bs,
                                                          close_body,
                                                          uu___19) ->
                                                           let uu___20 =
                                                             close_bs in
                                                           (match uu___20
                                                            with
                                                            | a_b::b_b::close_bs1
                                                                ->
                                                                let uu___21 =
                                                                  FStarC_List.splitAt
                                                                    (
                                                                    (FStarC_List.length
                                                                    close_bs1)
                                                                    -
                                                                    Prims.int_one)
                                                                    close_bs1 in
                                                                (match uu___21
                                                                 with
                                                                 | (is_bs,
                                                                    uu___22)
                                                                    ->
                                                                    let x_bv
                                                                    =
                                                                    let uu___23
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    b_b.FStarC_Syntax_Syntax.binder_bv in
                                                                    FStarC_Syntax_Syntax.gen_bv
                                                                    "x"
                                                                    FStar_Pervasives_Native.None
                                                                    uu___23 in
                                                                    let args1
                                                                    =
                                                                    FStarC_List.map
                                                                    (fun i_b
                                                                    ->
                                                                    let uu___23
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    i_b.FStarC_Syntax_Syntax.binder_bv in
                                                                    let uu___24
                                                                    =
                                                                    let uu___25
                                                                    =
                                                                    let uu___26
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    x_bv in
                                                                    FStarC_Syntax_Syntax.as_arg
                                                                    uu___26 in
                                                                    [uu___25] in
                                                                    FStarC_Syntax_Syntax.mk_Tm_app
                                                                    uu___23
                                                                    uu___24 r)
                                                                    is_bs in
                                                                    let args2
                                                                    =
                                                                    let uu___23
                                                                    =
                                                                    let uu___24
                                                                    =
                                                                    FStarC_Syntax_Subst.compress
                                                                    close_body in
                                                                    uu___24.FStarC_Syntax_Syntax.n in
                                                                    match uu___23
                                                                    with
                                                                    | 
                                                                    FStarC_Syntax_Syntax.Tm_app
                                                                    {
                                                                    FStarC_Syntax_Syntax.hd
                                                                    = uu___24;
                                                                    FStarC_Syntax_Syntax.args
                                                                    = a::args;_}
                                                                    ->
                                                                    FStarC_List.map
                                                                    FStar_Pervasives_Native.fst
                                                                    args
                                                                    | 
                                                                    uu___24
                                                                    ->
                                                                    FStarC_Errors.raise_error
                                                                    FStarC_Class_HasRange.hasRange_range
                                                                    r
                                                                    FStarC_Errors_Codes.Fatal_UnexpectedEffect
                                                                    ()
                                                                    (Obj.magic
                                                                    FStarC_Errors_Msg.is_error_message_string)
                                                                    (Obj.magic
                                                                    "close combinator body not a repr") in
                                                                    let env =
                                                                    FStarC_TypeChecker_Env.push_binders
                                                                    env01
                                                                    (FStarC_List.op_At
                                                                    (a_b ::
                                                                    b_b ::
                                                                    is_bs)
                                                                    [
                                                                    FStarC_Syntax_Syntax.mk_binder
                                                                    x_bv]) in
                                                                    let subcomp_ts
                                                                    =
                                                                    let uu___23
                                                                    =
                                                                    stronger_repr in
                                                                    match uu___23
                                                                    with
                                                                    | 
                                                                    (us2,
                                                                    uu___24,
                                                                    t) ->
                                                                    (us2, t) in
                                                                    let uu___23
                                                                    =
                                                                    FStarC_TypeChecker_Env.inst_tscheme_with
                                                                    subcomp_ts
                                                                    [
                                                                    FStarC_Syntax_Syntax.U_name
                                                                    (FStarC_List.hd
                                                                    us1)] in
                                                                    (match uu___23
                                                                    with
                                                                    | 
                                                                    (uu___24,
                                                                    subcomp_t)
                                                                    ->
                                                                    let uu___25
                                                                    =
                                                                    FStarC_Syntax_Util.arrow_formals_comp
                                                                    subcomp_t in
                                                                    (match uu___25
                                                                    with
                                                                    | 
                                                                    (a_b_subcomp::subcomp_bs,
                                                                    subcomp_c)
                                                                    ->
                                                                    let subcomp_substs
                                                                    =
                                                                    let uu___26
                                                                    =
                                                                    let uu___27
                                                                    =
                                                                    let uu___28
                                                                    =
                                                                    FStarC_Syntax_Syntax.bv_to_name
                                                                    a_b.FStarC_Syntax_Syntax.binder_bv in
                                                                    ((a_b_subcomp.FStarC_Syntax_Syntax.binder_bv),
                                                                    uu___28) in
                                                                    FStarC_Syntax_Syntax.NT
                                                                    uu___27 in
                                                                    [uu___26] in
                                                                    let uu___26
                                                                    =
                                                                    FStarC_List.splitAt
                                                                    (FStarC_List.length
                                                                    args1)
                                                                    subcomp_bs in
                                                                    (match uu___26
                                                                    with
                                                                    | 
                                                                    (subcomp_f_bs,
                                                                    subcomp_bs1)
                                                                    ->
                                                                    let subcomp_substs1
                                                                    =
                                                                    let uu___27
                                                                    =
                                                                    FStarC_List.map2
                                                                    (fun b
                                                                    arg1 ->
                                                                    FStarC_Syntax_Syntax.NT
                                                                    ((b.FStarC_Syntax_Syntax.binder_bv),
                                                                    arg1))
                                                                    subcomp_f_bs
                                                                    args1 in
                                                                    FStarC_List.op_At
                                                                    subcomp_substs
                                                                    uu___27 in
                                                                    let uu___27
                                                                    =
                                                                    FStarC_List.splitAt
                                                                    (FStarC_List.length
                                                                    args2)
                                                                    subcomp_bs1 in
                                                                    (match uu___27
                                                                    with
                                                                    | 
                                                                    (subcomp_g_bs,
                                                                    uu___28)
                                                                    ->
                                                                    let subcomp_substs2
                                                                    =
                                                                    let uu___29
                                                                    =
                                                                    FStarC_List.map2
                                                                    (fun b
                                                                    arg2 ->
                                                                    FStarC_Syntax_Syntax.NT
                                                                    ((b.FStarC_Syntax_Syntax.binder_bv),
                                                                    arg2))
                                                                    subcomp_g_bs
                                                                    args2 in
                                                                    FStarC_List.op_At
                                                                    subcomp_substs1
                                                                    uu___29 in
                                                                    let subcomp_c1
                                                                    =
                                                                    let uu___29
                                                                    =
                                                                    FStarC_Syntax_Subst.subst_comp
                                                                    subcomp_substs2
                                                                    subcomp_c in
                                                                    FStarC_TypeChecker_Env.unfold_effect_abbrev
                                                                    env
                                                                    uu___29 in
                                                                    let fml =
                                                                    FStarC_TypeChecker_Env.pure_precondition_for_trivial_post
                                                                    env
                                                                    (FStarC_List.hd
                                                                    subcomp_c1.FStarC_Syntax_Syntax.comp_univs)
                                                                    subcomp_c1.FStarC_Syntax_Syntax.result_typ
                                                                    (FStar_Pervasives_Native.fst
                                                                    (FStarC_List.hd
                                                                    subcomp_c1.FStarC_Syntax_Syntax.effect_args))
                                                                    r in
                                                                    FStarC_TypeChecker_Rel.force_trivial_guard
                                                                    env
                                                                    (FStarC_TypeChecker_Env.guard_of_guard_formula
                                                                    (FStarC_TypeChecker_Common.NonTrivial
                                                                    fml)))))))))))));
                                  (let tc_action env act =
                                     let env01 = env in
                                     let r =
                                       (act.FStarC_Syntax_Syntax.action_defn).FStarC_Syntax_Syntax.pos in
                                     if
                                       (FStarC_List.length
                                          act.FStarC_Syntax_Syntax.action_params)
                                         <> Prims.int_zero
                                     then
                                       (let uu___14 =
                                          let uu___15 =
                                            FStarC_Class_Show.show
                                              (FStarC_Class_Show.show_list
                                                 FStarC_Syntax_Print.showable_binder)
                                              act.FStarC_Syntax_Syntax.action_params in
                                          FStarC_Format.fmt3
                                            "Action %s:%s has non-empty action params (%s)"
                                            (FStarC_Ident.string_of_lid
                                               ed.FStarC_Syntax_Syntax.mname)
                                            (FStarC_Ident.string_of_lid
                                               act.FStarC_Syntax_Syntax.action_name)
                                            uu___15 in
                                        FStarC_Errors.raise_error
                                          FStarC_Class_HasRange.hasRange_range
                                          r
                                          FStarC_Errors_Codes.Fatal_MalformedActionDeclaration
                                          ()
                                          (Obj.magic
                                             FStarC_Errors_Msg.is_error_message_string)
                                          (Obj.magic uu___14))
                                     else ();
                                     (let uu___14 =
                                        let uu___15 =
                                          FStarC_Syntax_Subst.univ_var_opening
                                            act.FStarC_Syntax_Syntax.action_univs in
                                        match uu___15 with
                                        | (usubst, us) ->
                                            let uu___16 =
                                              FStarC_TypeChecker_Env.push_univ_vars
                                                env us in
                                            let uu___17 =
                                              let uu___18 =
                                                FStarC_Syntax_Subst.subst
                                                  usubst
                                                  act.FStarC_Syntax_Syntax.action_defn in
                                              let uu___19 =
                                                FStarC_Syntax_Subst.subst
                                                  usubst
                                                  act.FStarC_Syntax_Syntax.action_typ in
                                              {
                                                FStarC_Syntax_Syntax.action_name
                                                  =
                                                  (act.FStarC_Syntax_Syntax.action_name);
                                                FStarC_Syntax_Syntax.action_unqualified_name
                                                  =
                                                  (act.FStarC_Syntax_Syntax.action_unqualified_name);
                                                FStarC_Syntax_Syntax.action_univs
                                                  = us;
                                                FStarC_Syntax_Syntax.action_params
                                                  =
                                                  (act.FStarC_Syntax_Syntax.action_params);
                                                FStarC_Syntax_Syntax.action_defn
                                                  = uu___18;
                                                FStarC_Syntax_Syntax.action_typ
                                                  = uu___19
                                              } in
                                            (uu___16, uu___17) in
                                      match uu___14 with
                                      | (env1, act1) ->
                                          let act_typ =
                                            let uu___15 =
                                              let uu___16 =
                                                FStarC_Syntax_Subst.compress
                                                  act1.FStarC_Syntax_Syntax.action_typ in
                                              uu___16.FStarC_Syntax_Syntax.n in
                                            match uu___15 with
                                            | FStarC_Syntax_Syntax.Tm_arrow
                                                {
                                                  FStarC_Syntax_Syntax.bs1 =
                                                    bs;
                                                  FStarC_Syntax_Syntax.comp =
                                                    c;_}
                                                ->
                                                let ct =
                                                  FStarC_TypeChecker_Env.comp_to_comp_typ
                                                    env1 c in
                                                if
                                                  FStarC_Ident.lid_equals
                                                    ct.FStarC_Syntax_Syntax.effect_name
                                                    ed.FStarC_Syntax_Syntax.mname
                                                then
                                                  let repr_ts =
                                                    let uu___16 = repr in
                                                    match uu___16 with
                                                    | (us, t, uu___17) ->
                                                        (us, t) in
                                                  let repr1 =
                                                    let uu___16 =
                                                      FStarC_TypeChecker_Env.inst_tscheme_with
                                                        repr_ts
                                                        ct.FStarC_Syntax_Syntax.comp_univs in
                                                    FStar_Pervasives_Native.snd
                                                      uu___16 in
                                                  let repr2 =
                                                    FStarC_Syntax_Syntax.mk_Tm_app
                                                      repr1
                                                      ((FStarC_Syntax_Syntax.as_arg
                                                          ct.FStarC_Syntax_Syntax.result_typ)
                                                      ::
                                                      (ct.FStarC_Syntax_Syntax.effect_args))
                                                      r in
                                                  let c1 =
                                                    FStarC_Syntax_Syntax.mk_Total
                                                      repr2 in
                                                  FStarC_Syntax_Util.arrow bs
                                                    c1
                                                else
                                                  act1.FStarC_Syntax_Syntax.action_typ
                                            | uu___16 ->
                                                act1.FStarC_Syntax_Syntax.action_typ in
                                          let uu___15 =
                                            FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term
                                              env1 act_typ in
                                          (match uu___15 with
                                           | (act_typ1, uu___16, g_t) ->
                                               let uu___17 =
                                                 FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term
                                                   (let uu___18 =
                                                      FStarC_TypeChecker_Env.set_expected_typ
                                                        env1 act_typ1 in
                                                    {
                                                      FStarC_TypeChecker_Env.solver
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.solver);
                                                      FStarC_TypeChecker_Env.range
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.range);
                                                      FStarC_TypeChecker_Env.curmodule
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.curmodule);
                                                      FStarC_TypeChecker_Env.gamma
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.gamma);
                                                      FStarC_TypeChecker_Env.gamma_sig
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.gamma_sig);
                                                      FStarC_TypeChecker_Env.gamma_cache
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.gamma_cache);
                                                      FStarC_TypeChecker_Env.modules
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.modules);
                                                      FStarC_TypeChecker_Env.expected_typ
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.expected_typ);
                                                      FStarC_TypeChecker_Env.sigtab
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.sigtab);
                                                      FStarC_TypeChecker_Env.attrtab
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.attrtab);
                                                      FStarC_TypeChecker_Env.instantiate_imp
                                                        = false;
                                                      FStarC_TypeChecker_Env.effects
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.effects);
                                                      FStarC_TypeChecker_Env.generalize
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.generalize);
                                                      FStarC_TypeChecker_Env.letrecs
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.letrecs);
                                                      FStarC_TypeChecker_Env.top_level
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.top_level);
                                                      FStarC_TypeChecker_Env.check_uvars
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.check_uvars);
                                                      FStarC_TypeChecker_Env.use_eq_strict
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.use_eq_strict);
                                                      FStarC_TypeChecker_Env.is_iface
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.is_iface);
                                                      FStarC_TypeChecker_Env.admit
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.admit);
                                                      FStarC_TypeChecker_Env.phase1
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.phase1);
                                                      FStarC_TypeChecker_Env.failhard
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.failhard);
                                                      FStarC_TypeChecker_Env.flychecking
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.flychecking);
                                                      FStarC_TypeChecker_Env.uvar_subtyping
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.uvar_subtyping);
                                                      FStarC_TypeChecker_Env.intactics
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.intactics);
                                                      FStarC_TypeChecker_Env.nocoerce
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.nocoerce);
                                                      FStarC_TypeChecker_Env.tc_term
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.tc_term);
                                                      FStarC_TypeChecker_Env.typeof_tot_or_gtot_term
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.typeof_tot_or_gtot_term);
                                                      FStarC_TypeChecker_Env.universe_of
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.universe_of);
                                                      FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term);
                                                      FStarC_TypeChecker_Env.teq_nosmt_force
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.teq_nosmt_force);
                                                      FStarC_TypeChecker_Env.subtype_nosmt_force
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.subtype_nosmt_force);
                                                      FStarC_TypeChecker_Env.qtbl_name_and_index
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.qtbl_name_and_index);
                                                      FStarC_TypeChecker_Env.normalized_eff_names
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.normalized_eff_names);
                                                      FStarC_TypeChecker_Env.fv_delta_depths
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.fv_delta_depths);
                                                      FStarC_TypeChecker_Env.proof_ns
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.proof_ns);
                                                      FStarC_TypeChecker_Env.synth_hook
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.synth_hook);
                                                      FStarC_TypeChecker_Env.try_solve_implicits_hook
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.try_solve_implicits_hook);
                                                      FStarC_TypeChecker_Env.splice
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.splice);
                                                      FStarC_TypeChecker_Env.mpreprocess
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.mpreprocess);
                                                      FStarC_TypeChecker_Env.postprocess
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.postprocess);
                                                      FStarC_TypeChecker_Env.identifier_info
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.identifier_info);
                                                      FStarC_TypeChecker_Env.tc_hooks
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.tc_hooks);
                                                      FStarC_TypeChecker_Env.dsenv
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.dsenv);
                                                      FStarC_TypeChecker_Env.nbe
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.nbe);
                                                      FStarC_TypeChecker_Env.strict_args_tab
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.strict_args_tab);
                                                      FStarC_TypeChecker_Env.erasable_types_tab
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.erasable_types_tab);
                                                      FStarC_TypeChecker_Env.enable_defer_to_tac
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.enable_defer_to_tac);
                                                      FStarC_TypeChecker_Env.unif_allow_ref_guards
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.unif_allow_ref_guards);
                                                      FStarC_TypeChecker_Env.erase_erasable_args
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.erase_erasable_args);
                                                      FStarC_TypeChecker_Env.core_check
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.core_check);
                                                      FStarC_TypeChecker_Env.missing_decl
                                                        =
                                                        (uu___18.FStarC_TypeChecker_Env.missing_decl)
                                                    })
                                                   act1.FStarC_Syntax_Syntax.action_defn in
                                               (match uu___17 with
                                                | (act_defn, uu___18, g_d) ->
                                                    ((let uu___20 =
                                                        let uu___21 =
                                                          FStarC_Debug.medium
                                                            () in
                                                        if uu___21
                                                        then true
                                                        else
                                                          FStarC_Effect.op_Bang
                                                            dbg_LayeredEffectsTc in
                                                      if uu___20
                                                      then
                                                        let uu___21 =
                                                          FStarC_Class_Show.show
                                                            FStarC_Syntax_Print.showable_term
                                                            act_defn in
                                                        let uu___22 =
                                                          FStarC_Class_Show.show
                                                            FStarC_Syntax_Print.showable_term
                                                            act_typ1 in
                                                        FStarC_Format.print2
                                                          "Typechecked action definition: %s and action type: %s\n"
                                                          uu___21 uu___22
                                                      else ());
                                                     (let uu___20 =
                                                        let act_typ2 =
                                                          FStarC_TypeChecker_Normalize.normalize
                                                            [FStarC_TypeChecker_Env.Beta]
                                                            env1 act_typ1 in
                                                        let uu___21 =
                                                          let uu___22 =
                                                            FStarC_Syntax_Subst.compress
                                                              act_typ2 in
                                                          uu___22.FStarC_Syntax_Syntax.n in
                                                        match uu___21 with
                                                        | FStarC_Syntax_Syntax.Tm_arrow
                                                            {
                                                              FStarC_Syntax_Syntax.bs1
                                                                = bs;
                                                              FStarC_Syntax_Syntax.comp
                                                                = uu___22;_}
                                                            ->
                                                            let bs1 =
                                                              FStarC_Syntax_Subst.open_binders
                                                                bs in
                                                            let env2 =
                                                              FStarC_TypeChecker_Env.push_binders
                                                                env1 bs1 in
                                                            let uu___23 =
                                                              FStarC_Syntax_Util.type_u
                                                                () in
                                                            (match uu___23
                                                             with
                                                             | (t, u) ->
                                                                 let reason =
                                                                   FStarC_Format.fmt2
                                                                    "implicit for return type of action %s:%s"
                                                                    (FStarC_Ident.string_of_lid
                                                                    ed.FStarC_Syntax_Syntax.mname)
                                                                    (FStarC_Ident.string_of_lid
                                                                    act1.FStarC_Syntax_Syntax.action_name) in
                                                                 let uu___24
                                                                   =
                                                                   FStarC_TypeChecker_Util.new_implicit_var
                                                                    reason r
                                                                    env2 t
                                                                    false in
                                                                 (match uu___24
                                                                  with
                                                                  | (a_tm,
                                                                    uu___25,
                                                                    g_tm) ->
                                                                    let uu___26
                                                                    =
                                                                    fresh_repr
                                                                    r env2 u
                                                                    a_tm in
                                                                    (match uu___26
                                                                    with
                                                                    | 
                                                                    (repr1,
                                                                    g) ->
                                                                    let uu___27
                                                                    =
                                                                    let uu___28
                                                                    =
                                                                    FStarC_Syntax_Syntax.mk_Total
                                                                    repr1 in
                                                                    FStarC_Syntax_Util.arrow
                                                                    bs1
                                                                    uu___28 in
                                                                    let uu___28
                                                                    =
                                                                    FStarC_TypeChecker_Env.conj_guard
                                                                    g g_tm in
                                                                    (uu___27,
                                                                    uu___28))))
                                                        | uu___22 ->
                                                            let uu___23 =
                                                              let uu___24 =
                                                                FStarC_Class_Show.show
                                                                  FStarC_Ident.showable_lident
                                                                  ed.FStarC_Syntax_Syntax.mname in
                                                              let uu___25 =
                                                                FStarC_Class_Show.show
                                                                  FStarC_Ident.showable_lident
                                                                  act1.FStarC_Syntax_Syntax.action_name in
                                                              let uu___26 =
                                                                FStarC_Class_Show.show
                                                                  FStarC_Syntax_Print.showable_term
                                                                  act_typ2 in
                                                              FStarC_Format.fmt3
                                                                "Unexpected non-function type for action %s:%s (%s)"
                                                                uu___24
                                                                uu___25
                                                                uu___26 in
                                                            FStarC_Errors.raise_error
                                                              FStarC_Class_HasRange.hasRange_range
                                                              r
                                                              FStarC_Errors_Codes.Fatal_ActionMustHaveFunctionType
                                                              ()
                                                              (Obj.magic
                                                                 FStarC_Errors_Msg.is_error_message_string)
                                                              (Obj.magic
                                                                 uu___23) in
                                                      match uu___20 with
                                                      | (k, g_k) ->
                                                          ((let uu___22 =
                                                              let uu___23 =
                                                                FStarC_Debug.medium
                                                                  () in
                                                              if uu___23
                                                              then true
                                                              else
                                                                FStarC_Effect.op_Bang
                                                                  dbg_LayeredEffectsTc in
                                                            if uu___22
                                                            then
                                                              let uu___23 =
                                                                FStarC_Class_Show.show
                                                                  FStarC_Syntax_Print.showable_term
                                                                  k in
                                                              FStarC_Format.print1
                                                                "Expected action type: %s\n"
                                                                uu___23
                                                            else ());
                                                           (let g =
                                                              FStarC_TypeChecker_Rel.teq
                                                                env1 act_typ1
                                                                k in
                                                            FStarC_List.iter
                                                              (FStarC_TypeChecker_Rel.force_trivial_guard
                                                                 env1)
                                                              [g_t;
                                                              g_d;
                                                              g_k;
                                                              g];
                                                            (let uu___24 =
                                                               let uu___25 =
                                                                 FStarC_Debug.medium
                                                                   () in
                                                               if uu___25
                                                               then true
                                                               else
                                                                 FStarC_Effect.op_Bang
                                                                   dbg_LayeredEffectsTc in
                                                             if uu___24
                                                             then
                                                               let uu___25 =
                                                                 FStarC_Class_Show.show
                                                                   FStarC_Syntax_Print.showable_term
                                                                   k in
                                                               FStarC_Format.print1
                                                                 "Expected action type after unification: %s\n"
                                                                 uu___25
                                                             else ());
                                                            (let act_typ2 =
                                                               let err_msg t
                                                                 =
                                                                 let uu___24
                                                                   =
                                                                   FStarC_Class_Show.show
                                                                    FStarC_Syntax_Print.showable_term
                                                                    t in
                                                                 FStarC_Format.fmt3
                                                                   "Unexpected (k-)type of action %s:%s, expected bs -> repr<u> i_1 ... i_n, found: %s"
                                                                   (FStarC_Ident.string_of_lid
                                                                    ed.FStarC_Syntax_Syntax.mname)
                                                                   (FStarC_Ident.string_of_lid
                                                                    act1.FStarC_Syntax_Syntax.action_name)
                                                                   uu___24 in
                                                               let repr_args
                                                                 t =
                                                                 let uu___24
                                                                   =
                                                                   let uu___25
                                                                    =
                                                                    FStarC_Syntax_Subst.compress
                                                                    t in
                                                                   uu___25.FStarC_Syntax_Syntax.n in
                                                                 match uu___24
                                                                 with
                                                                 | FStarC_Syntax_Syntax.Tm_app
                                                                    {
                                                                    FStarC_Syntax_Syntax.hd
                                                                    = head;
                                                                    FStarC_Syntax_Syntax.args
                                                                    = a::is;_}
                                                                    ->
                                                                    let uu___25
                                                                    =
                                                                    let uu___26
                                                                    =
                                                                    FStarC_Syntax_Subst.compress
                                                                    head in
                                                                    uu___26.FStarC_Syntax_Syntax.n in
                                                                    (match uu___25
                                                                    with
                                                                    | 
                                                                    FStarC_Syntax_Syntax.Tm_uinst
                                                                    (uu___26,
                                                                    us) ->
                                                                    (us,
                                                                    (FStar_Pervasives_Native.fst
                                                                    a), is)
                                                                    | 
                                                                    uu___26
                                                                    ->
                                                                    let uu___27
                                                                    =
                                                                    err_msg t in
                                                                    FStarC_Errors.raise_error
                                                                    FStarC_Class_HasRange.hasRange_range
                                                                    r
                                                                    FStarC_Errors_Codes.Fatal_ActionMustHaveFunctionType
                                                                    ()
                                                                    (Obj.magic
                                                                    FStarC_Errors_Msg.is_error_message_string)
                                                                    (Obj.magic
                                                                    uu___27))
                                                                 | uu___25 ->
                                                                    let uu___26
                                                                    =
                                                                    err_msg t in
                                                                    FStarC_Errors.raise_error
                                                                    FStarC_Class_HasRange.hasRange_range
                                                                    r
                                                                    FStarC_Errors_Codes.Fatal_ActionMustHaveFunctionType
                                                                    ()
                                                                    (Obj.magic
                                                                    FStarC_Errors_Msg.is_error_message_string)
                                                                    (Obj.magic
                                                                    uu___26) in
                                                               let k1 =
                                                                 FStarC_TypeChecker_Normalize.normalize
                                                                   [FStarC_TypeChecker_Env.Beta]
                                                                   env1 k in
                                                               let uu___24 =
                                                                 let uu___25
                                                                   =
                                                                   FStarC_Syntax_Subst.compress
                                                                    k1 in
                                                                 uu___25.FStarC_Syntax_Syntax.n in
                                                               match uu___24
                                                               with
                                                               | FStarC_Syntax_Syntax.Tm_arrow
                                                                   {
                                                                    FStarC_Syntax_Syntax.bs1
                                                                    = bs;
                                                                    FStarC_Syntax_Syntax.comp
                                                                    = c;_}
                                                                   ->
                                                                   let uu___25
                                                                    =
                                                                    FStarC_Syntax_Subst.open_comp
                                                                    bs c in
                                                                   (match uu___25
                                                                    with
                                                                    | 
                                                                    (bs1, c1)
                                                                    ->
                                                                    let uu___26
                                                                    =
                                                                    repr_args
                                                                    (FStarC_Syntax_Util.comp_result
                                                                    c1) in
                                                                    (match uu___26
                                                                    with
                                                                    | 
                                                                    (us, a,
                                                                    is) ->
                                                                    let ct =
                                                                    {
                                                                    FStarC_Syntax_Syntax.comp_univs
                                                                    = us;
                                                                    FStarC_Syntax_Syntax.effect_name
                                                                    =
                                                                    (ed.FStarC_Syntax_Syntax.mname);
                                                                    FStarC_Syntax_Syntax.result_typ
                                                                    = a;
                                                                    FStarC_Syntax_Syntax.effect_args
                                                                    = is;
                                                                    FStarC_Syntax_Syntax.flags
                                                                    = []
                                                                    } in
                                                                    let uu___27
                                                                    =
                                                                    FStarC_Syntax_Syntax.mk_Comp
                                                                    ct in
                                                                    FStarC_Syntax_Util.arrow
                                                                    bs1
                                                                    uu___27))
                                                               | uu___25 ->
                                                                   let uu___26
                                                                    =
                                                                    err_msg
                                                                    k1 in
                                                                   FStarC_Errors.raise_error
                                                                    FStarC_Class_HasRange.hasRange_range
                                                                    r
                                                                    FStarC_Errors_Codes.Fatal_ActionMustHaveFunctionType
                                                                    ()
                                                                    (Obj.magic
                                                                    FStarC_Errors_Msg.is_error_message_string)
                                                                    (Obj.magic
                                                                    uu___26) in
                                                             (let uu___25 =
                                                                let uu___26 =
                                                                  FStarC_Debug.medium
                                                                    () in
                                                                if uu___26
                                                                then true
                                                                else
                                                                  FStarC_Effect.op_Bang
                                                                    dbg_LayeredEffectsTc in
                                                              if uu___25
                                                              then
                                                                let uu___26 =
                                                                  FStarC_Class_Show.show
                                                                    FStarC_Syntax_Print.showable_term
                                                                    act_typ2 in
                                                                FStarC_Format.print1
                                                                  "Action type after injecting it into the monad: %s\n"
                                                                  uu___26
                                                              else ());
                                                             (let act2 =
                                                                let uu___25 =
                                                                  FStarC_TypeChecker_Generalize.generalize_universes
                                                                    env1
                                                                    act_defn in
                                                                match uu___25
                                                                with
                                                                | (us,
                                                                   act_defn1)
                                                                    ->
                                                                    if
                                                                    act1.FStarC_Syntax_Syntax.action_univs
                                                                    = []
                                                                    then
                                                                    let uu___26
                                                                    =
                                                                    FStarC_Syntax_Subst.close_univ_vars
                                                                    us
                                                                    act_typ2 in
                                                                    {
                                                                    FStarC_Syntax_Syntax.action_name
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_name);
                                                                    FStarC_Syntax_Syntax.action_unqualified_name
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_unqualified_name);
                                                                    FStarC_Syntax_Syntax.action_univs
                                                                    = us;
                                                                    FStarC_Syntax_Syntax.action_params
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_params);
                                                                    FStarC_Syntax_Syntax.action_defn
                                                                    =
                                                                    act_defn1;
                                                                    FStarC_Syntax_Syntax.action_typ
                                                                    = uu___26
                                                                    }
                                                                    else
                                                                    (let uu___26
                                                                    =
                                                                    if
                                                                    (FStarC_List.length
                                                                    us) =
                                                                    (FStarC_List.length
                                                                    act1.FStarC_Syntax_Syntax.action_univs)
                                                                    then
                                                                    FStarC_List.forall2
                                                                    (fun u1
                                                                    u2 ->
                                                                    (FStarC_Syntax_Syntax.order_univ_name
                                                                    u1 u2) =
                                                                    Prims.int_zero)
                                                                    us
                                                                    act1.FStarC_Syntax_Syntax.action_univs
                                                                    else
                                                                    false in
                                                                    if
                                                                    uu___26
                                                                    then
                                                                    let uu___27
                                                                    =
                                                                    FStarC_Syntax_Subst.close_univ_vars
                                                                    act1.FStarC_Syntax_Syntax.action_univs
                                                                    act_typ2 in
                                                                    {
                                                                    FStarC_Syntax_Syntax.action_name
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_name);
                                                                    FStarC_Syntax_Syntax.action_unqualified_name
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_unqualified_name);
                                                                    FStarC_Syntax_Syntax.action_univs
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_univs);
                                                                    FStarC_Syntax_Syntax.action_params
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_params);
                                                                    FStarC_Syntax_Syntax.action_defn
                                                                    =
                                                                    act_defn1;
                                                                    FStarC_Syntax_Syntax.action_typ
                                                                    = uu___27
                                                                    }
                                                                    else
                                                                    (let uu___27
                                                                    =
                                                                    let uu___28
                                                                    =
                                                                    FStarC_Class_Show.show
                                                                    (FStarC_Class_Show.show_list
                                                                    FStarC_Ident.showable_ident)
                                                                    us in
                                                                    let uu___29
                                                                    =
                                                                    FStarC_Class_Show.show
                                                                    (FStarC_Class_Show.show_list
                                                                    FStarC_Ident.showable_ident)
                                                                    act1.FStarC_Syntax_Syntax.action_univs in
                                                                    FStarC_Format.fmt4
                                                                    "Expected and generalized universes in the declaration for %s:%s are different, input: %s, but after gen: %s"
                                                                    (FStarC_Ident.string_of_lid
                                                                    ed.FStarC_Syntax_Syntax.mname)
                                                                    (FStarC_Ident.string_of_lid
                                                                    act1.FStarC_Syntax_Syntax.action_name)
                                                                    uu___28
                                                                    uu___29 in
                                                                    FStarC_Errors.raise_error
                                                                    FStarC_Class_HasRange.hasRange_range
                                                                    r
                                                                    FStarC_Errors_Codes.Fatal_UnexpectedNumberOfUniverse
                                                                    ()
                                                                    (Obj.magic
                                                                    FStarC_Errors_Msg.is_error_message_string)
                                                                    (Obj.magic
                                                                    uu___27))) in
                                                              act2))))))))) in
                                   let tc_action_with_ctx env act =
                                     FStarC_Errors.with_ctx
                                       (FStarC_Format.fmt1
                                          "While checking the action %s"
                                          (FStarC_Ident.string_of_lid
                                             act.FStarC_Syntax_Syntax.action_name))
                                       (fun uu___13 -> tc_action env act) in
                                   let extraction_mode =
                                     let has_primitive_extraction =
                                       FStarC_Syntax_Util.has_attribute
                                         ed.FStarC_Syntax_Syntax.eff_attrs
                                         FStarC_Parser_Const.primitive_extraction_attr in
                                     let is_reifiable =
                                       FStarC_List.contains
                                         FStarC_Syntax_Syntax.Reifiable quals in
                                     if has_primitive_extraction
                                     then
                                       FStarC_Syntax_Syntax.Extract_primitive
                                     else
                                       (let uu___13 =
                                          let uu___14 =
                                            let uu___15 = signature in
                                            match uu___15 with
                                            | (us, t, uu___16) -> (us, t) in
                                          match uu___14 with
                                          | (us, t) ->
                                              let uu___15 =
                                                let uu___16 =
                                                  FStarC_Syntax_Subst.compress
                                                    t in
                                                uu___16.FStarC_Syntax_Syntax.n in
                                              (match uu___15 with
                                               | FStarC_Syntax_Syntax.Tm_arrow
                                                   {
                                                     FStarC_Syntax_Syntax.bs1
                                                       = bs;
                                                     FStarC_Syntax_Syntax.comp
                                                       = uu___16;_}
                                                   ->
                                                   let uu___17 =
                                                     FStarC_Syntax_Subst.open_binders
                                                       bs in
                                                   (match uu___17 with
                                                    | a_b::rest_bs ->
                                                        (us, a_b, rest_bs))
                                               | uu___16 ->
                                                   FStarC_Effect.failwith
                                                     "Impossible!") in
                                        match uu___13 with
                                        | (us, a_b, rest_bs) ->
                                            let env =
                                              FStarC_TypeChecker_Env.push_univ_vars
                                                env0 us in
                                            let env1 =
                                              FStarC_TypeChecker_Env.push_binders
                                                env [a_b] in
                                            let uu___14 =
                                              FStarC_List.fold_left
                                                (fun uu___15 b ->
                                                   match uu___15 with
                                                   | (env2, r) ->
                                                       let r1 =
                                                         if r
                                                         then
                                                           FStarC_TypeChecker_Normalize.non_info_norm
                                                             env2
                                                             (b.FStarC_Syntax_Syntax.binder_bv).FStarC_Syntax_Syntax.sort
                                                         else false in
                                                       let uu___16 =
                                                         FStarC_TypeChecker_Env.push_binders
                                                           env2 [b] in
                                                       (uu___16, r1))
                                                (env1, true) rest_bs in
                                            (match uu___14 with
                                             | (uu___15, r) ->
                                                 if
                                                   (r &&
                                                      (FStarC_Syntax_Syntax.uu___is_Substitutive_combinator
                                                         bind_kind))
                                                     &&
                                                     (is_reifiable ||
                                                        (FStarC_Ident.lid_equals
                                                           ed.FStarC_Syntax_Syntax.mname
                                                           FStarC_Parser_Const.effect_TAC_lid))
                                                 then
                                                   FStarC_Syntax_Syntax.Extract_reify
                                                 else
                                                   (let m =
                                                      if Prims.op_Negation r
                                                      then
                                                        "one or more effect indices are informative"
                                                      else
                                                        if
                                                          Prims.op_Negation
                                                            (FStarC_Syntax_Syntax.uu___is_Substitutive_combinator
                                                               bind_kind)
                                                        then
                                                          "bind is not substitutive"
                                                        else
                                                          "the effect is not reifiable" in
                                                    FStarC_Syntax_Syntax.Extract_none
                                                      m))) in
                                   (let uu___14 =
                                      FStarC_Effect.op_Bang
                                        dbg_LayeredEffectsTc in
                                    if uu___14
                                    then
                                      let uu___15 =
                                        FStarC_Class_Show.show
                                          FStarC_Ident.showable_lident
                                          ed.FStarC_Syntax_Syntax.mname in
                                      let uu___16 =
                                        FStarC_Class_Show.show
                                          FStarC_Syntax_Syntax.showable_eff_extraction_mode
                                          extraction_mode in
                                      FStarC_Format.print2
                                        "Effect %s has extraction mode %s\n"
                                        uu___15 uu___16
                                    else ());
                                   (let tschemes_of uu___14 k =
                                      match uu___14 with
                                      | (us, t, ty) -> ((us, t), (us, ty), k) in
                                    let tschemes_of2 uu___14 =
                                      match uu___14 with
                                      | (us, t, ty) -> ((us, t), (us, ty)) in
                                    let combinators =
                                      FStarC_Syntax_Syntax.Layered_eff
                                        {
                                          FStarC_Syntax_Syntax.l_repr =
                                            (tschemes_of2 repr);
                                          FStarC_Syntax_Syntax.l_return =
                                            (tschemes_of2 return_repr);
                                          FStarC_Syntax_Syntax.l_bind =
                                            (tschemes_of bind_repr
                                               (FStar_Pervasives_Native.Some
                                                  bind_kind));
                                          FStarC_Syntax_Syntax.l_subcomp =
                                            (tschemes_of stronger_repr
                                               (FStar_Pervasives_Native.Some
                                                  subcomp_kind));
                                          FStarC_Syntax_Syntax.l_if_then_else
                                            =
                                            (tschemes_of if_then_else
                                               (FStar_Pervasives_Native.Some
                                                  ite_kind));
                                          FStarC_Syntax_Syntax.l_close =
                                            (match close_ with
                                             | FStar_Pervasives_Native.None
                                                 ->
                                                 FStar_Pervasives_Native.None
                                             | FStar_Pervasives_Native.Some
                                                 (us, t, ty) ->
                                                 FStar_Pervasives_Native.Some
                                                   ((us, t), (us, ty)))
                                        } in
                                    let uu___14 =
                                      FStarC_List.map
                                        (tc_action_with_ctx env0)
                                        ed.FStarC_Syntax_Syntax.actions in
                                    {
                                      FStarC_Syntax_Syntax.mname =
                                        (ed.FStarC_Syntax_Syntax.mname);
                                      FStarC_Syntax_Syntax.cattributes =
                                        (ed.FStarC_Syntax_Syntax.cattributes);
                                      FStarC_Syntax_Syntax.univs =
                                        (ed.FStarC_Syntax_Syntax.univs);
                                      FStarC_Syntax_Syntax.binders =
                                        (ed.FStarC_Syntax_Syntax.binders);
                                      FStarC_Syntax_Syntax.signature =
                                        (FStarC_Syntax_Syntax.Layered_eff_sig
                                           (num_effect_params,
                                             (let uu___15 = signature in
                                              match uu___15 with
                                              | (us, t, uu___16) -> (us, t))));
                                      FStarC_Syntax_Syntax.combinators =
                                        combinators;
                                      FStarC_Syntax_Syntax.actions = uu___14;
                                      FStarC_Syntax_Syntax.eff_attrs =
                                        (ed.FStarC_Syntax_Syntax.eff_attrs);
                                      FStarC_Syntax_Syntax.extraction_mode =
                                        extraction_mode
                                    }))))))))))))))
let tc_non_layered_eff_decl (env0 : FStarC_TypeChecker_Env.env)
  (ed : FStarC_Syntax_Syntax.eff_decl)
  (_quals : FStarC_Syntax_Syntax.qualifier Prims.list)
  (_attrs : FStarC_Syntax_Syntax.attribute Prims.list) :
  FStarC_Syntax_Syntax.eff_decl=
  FStarC_Errors.with_ctx
    (FStarC_Format.fmt1
       "While checking effect definition \226\128\152%s\226\128\153"
       (FStarC_Ident.string_of_lid ed.FStarC_Syntax_Syntax.mname))
    (fun uu___ ->
       (let uu___2 = FStarC_Effect.op_Bang dbg in
        if uu___2
        then
          let uu___3 =
            FStarC_Class_Show.show FStarC_Syntax_Print.showable_eff_decl ed in
          FStarC_Format.print1 "Typechecking eff_decl: \n\t%s\n" uu___3
        else ());
       (let uu___2 =
          let uu___3 =
            FStarC_Syntax_Subst.univ_var_opening
              ed.FStarC_Syntax_Syntax.univs in
          match uu___3 with
          | (ed_univs_subst, ed_univs) ->
              let bs =
                let uu___4 =
                  FStarC_Syntax_Subst.subst_binders ed_univs_subst
                    ed.FStarC_Syntax_Syntax.binders in
                FStarC_Syntax_Subst.open_binders uu___4 in
              let uu___4 =
                let uu___5 =
                  FStarC_TypeChecker_Env.push_univ_vars env0 ed_univs in
                FStarC_TypeChecker_TcTerm.tc_tparams uu___5 bs in
              (match uu___4 with
               | (bs1, uu___5, uu___6) ->
                   let uu___7 =
                     let tmp_t =
                       let uu___8 =
                         FStarC_Syntax_Syntax.mk_Total
                           FStarC_Syntax_Syntax.t_unit in
                       FStarC_Syntax_Util.arrow bs1 uu___8 in
                     let uu___8 =
                       FStarC_TypeChecker_Generalize.generalize_universes
                         env0 tmp_t in
                     match uu___8 with
                     | (us, tmp_t1) ->
                         let uu___9 =
                           let uu___10 =
                             let uu___11 =
                               FStarC_Syntax_Util.arrow_formals tmp_t1 in
                             FStar_Pervasives_Native.fst uu___11 in
                           FStarC_Syntax_Subst.close_binders uu___10 in
                         (us, uu___9) in
                   (match uu___7 with
                    | (us, bs2) ->
                        (match ed_univs with
                         | [] -> (us, bs2)
                         | uu___8 ->
                             let uu___9 =
                               if
                                 (FStarC_List.length ed_univs) =
                                   (FStarC_List.length us)
                               then
                                 FStarC_List.forall2
                                   (fun u1 u2 ->
                                      (FStarC_Syntax_Syntax.order_univ_name
                                         u1 u2)
                                        = Prims.int_zero) ed_univs us
                               else false in
                             if uu___9
                             then (us, bs2)
                             else
                               (let uu___10 =
                                  let uu___11 =
                                    let uu___12 =
                                      let uu___13 =
                                        let uu___14 =
                                          FStarC_Class_PP.pp
                                            FStarC_Class_PP.pp_int
                                            (FStarC_List.length ed_univs) in
                                        let uu___15 =
                                          let uu___16 =
                                            FStarC_Class_PP.pp
                                              FStarC_Class_PP.pp_int
                                              (FStarC_List.length us) in
                                          FStar_Pprint.op_Hat_Slash_Hat
                                            (FStarC_Errors_Msg.text
                                               "but found") uu___16 in
                                        FStar_Pprint.op_Hat_Slash_Hat uu___14
                                          uu___15 in
                                      FStar_Pprint.op_Hat_Slash_Hat
                                        (FStarC_Errors_Msg.text "Expected")
                                        uu___13 in
                                    [uu___12] in
                                  (FStar_Pprint.op_Hat_Slash_Hat
                                     (FStarC_Errors_Msg.text
                                        "Expected and generalized universes in effect declaration for")
                                     (FStar_Pprint.op_Hat_Slash_Hat
                                        (FStar_Pprint.doc_of_string
                                           (FStarC_Ident.string_of_lid
                                              ed.FStarC_Syntax_Syntax.mname))
                                        (FStarC_Errors_Msg.text
                                           "are different")))
                                    :: uu___11 in
                                FStarC_Errors.raise_error
                                  FStarC_Ident.hasrange_lident
                                  ed.FStarC_Syntax_Syntax.mname
                                  FStarC_Errors_Codes.Fatal_UnexpectedNumberOfUniverse
                                  ()
                                  (Obj.magic
                                     FStarC_Errors_Msg.is_error_message_list_doc)
                                  (Obj.magic uu___10))))) in
        match uu___2 with
        | (us, bs) ->
            let ed1 =
              {
                FStarC_Syntax_Syntax.mname = (ed.FStarC_Syntax_Syntax.mname);
                FStarC_Syntax_Syntax.cattributes =
                  (ed.FStarC_Syntax_Syntax.cattributes);
                FStarC_Syntax_Syntax.univs = us;
                FStarC_Syntax_Syntax.binders = bs;
                FStarC_Syntax_Syntax.signature =
                  (ed.FStarC_Syntax_Syntax.signature);
                FStarC_Syntax_Syntax.combinators =
                  (ed.FStarC_Syntax_Syntax.combinators);
                FStarC_Syntax_Syntax.actions =
                  (ed.FStarC_Syntax_Syntax.actions);
                FStarC_Syntax_Syntax.eff_attrs =
                  (ed.FStarC_Syntax_Syntax.eff_attrs);
                FStarC_Syntax_Syntax.extraction_mode =
                  (ed.FStarC_Syntax_Syntax.extraction_mode)
              } in
            let uu___3 = FStarC_Syntax_Subst.univ_var_opening us in
            (match uu___3 with
             | (ed_univs_subst, ed_univs) ->
                 let uu___4 =
                   let uu___5 =
                     FStarC_Syntax_Subst.subst_binders ed_univs_subst bs in
                   FStarC_Syntax_Subst.open_binders' uu___5 in
                 (match uu___4 with
                  | (ed_bs, ed_bs_subst) ->
                      let ed2 =
                        let op uu___5 =
                          match uu___5 with
                          | (us1, t) ->
                              let t1 =
                                let uu___6 =
                                  FStarC_Syntax_Subst.shift_subst
                                    ((FStarC_List.length ed_bs) +
                                       (FStarC_List.length us1))
                                    ed_univs_subst in
                                FStarC_Syntax_Subst.subst uu___6 t in
                              let uu___6 =
                                let uu___7 =
                                  FStarC_Syntax_Subst.shift_subst
                                    (FStarC_List.length us1) ed_bs_subst in
                                FStarC_Syntax_Subst.subst uu___7 t1 in
                              (us1, uu___6) in
                        let uu___5 =
                          FStarC_Syntax_Util.apply_eff_sig op
                            ed1.FStarC_Syntax_Syntax.signature in
                        let uu___6 =
                          FStarC_Syntax_Util.apply_eff_combinators op
                            ed1.FStarC_Syntax_Syntax.combinators in
                        let uu___7 =
                          FStarC_List.map
                            (fun a ->
                               let uu___8 =
                                 let uu___9 =
                                   op
                                     ((a.FStarC_Syntax_Syntax.action_univs),
                                       (a.FStarC_Syntax_Syntax.action_defn)) in
                                 FStar_Pervasives_Native.snd uu___9 in
                               let uu___9 =
                                 let uu___10 =
                                   op
                                     ((a.FStarC_Syntax_Syntax.action_univs),
                                       (a.FStarC_Syntax_Syntax.action_typ)) in
                                 FStar_Pervasives_Native.snd uu___10 in
                               {
                                 FStarC_Syntax_Syntax.action_name =
                                   (a.FStarC_Syntax_Syntax.action_name);
                                 FStarC_Syntax_Syntax.action_unqualified_name
                                   =
                                   (a.FStarC_Syntax_Syntax.action_unqualified_name);
                                 FStarC_Syntax_Syntax.action_univs =
                                   (a.FStarC_Syntax_Syntax.action_univs);
                                 FStarC_Syntax_Syntax.action_params =
                                   (a.FStarC_Syntax_Syntax.action_params);
                                 FStarC_Syntax_Syntax.action_defn = uu___8;
                                 FStarC_Syntax_Syntax.action_typ = uu___9
                               }) ed1.FStarC_Syntax_Syntax.actions in
                        {
                          FStarC_Syntax_Syntax.mname =
                            (ed1.FStarC_Syntax_Syntax.mname);
                          FStarC_Syntax_Syntax.cattributes =
                            (ed1.FStarC_Syntax_Syntax.cattributes);
                          FStarC_Syntax_Syntax.univs =
                            (ed1.FStarC_Syntax_Syntax.univs);
                          FStarC_Syntax_Syntax.binders =
                            (ed1.FStarC_Syntax_Syntax.binders);
                          FStarC_Syntax_Syntax.signature = uu___5;
                          FStarC_Syntax_Syntax.combinators = uu___6;
                          FStarC_Syntax_Syntax.actions = uu___7;
                          FStarC_Syntax_Syntax.eff_attrs =
                            (ed1.FStarC_Syntax_Syntax.eff_attrs);
                          FStarC_Syntax_Syntax.extraction_mode =
                            (ed1.FStarC_Syntax_Syntax.extraction_mode)
                        } in
                      ((let uu___6 = FStarC_Effect.op_Bang dbg in
                        if uu___6
                        then
                          let uu___7 =
                            FStarC_Class_Show.show
                              FStarC_Syntax_Print.showable_eff_decl ed2 in
                          FStarC_Format.print1
                            "After typechecking binders eff_decl: \n\t%s\n"
                            uu___7
                        else ());
                       (let env =
                          let uu___6 =
                            FStarC_TypeChecker_Env.push_univ_vars env0
                              ed_univs in
                          FStarC_TypeChecker_Env.push_binders uu___6 ed_bs in
                        let check_and_gen' comb n env_opt us_t k =
                          let uu___6 = us_t in
                          match uu___6 with
                          | (us1, t) ->
                              let env1 =
                                if
                                  FStar_Pervasives_Native.uu___is_Some
                                    env_opt
                                then FStarC_Option.must env_opt
                                else env in
                              let uu___7 =
                                FStarC_Syntax_Subst.open_univ_vars us1 t in
                              (match uu___7 with
                               | (us2, t1) ->
                                   let t2 =
                                     match k with
                                     | FStar_Pervasives_Native.Some k1 ->
                                         let uu___8 =
                                           FStarC_TypeChecker_Env.push_univ_vars
                                             env1 us2 in
                                         FStarC_TypeChecker_TcTerm.tc_check_trivial_guard
                                           uu___8 t1 k1
                                     | FStar_Pervasives_Native.None ->
                                         let uu___8 =
                                           let uu___9 =
                                             FStarC_TypeChecker_Env.push_univ_vars
                                               env1 us2 in
                                           FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term
                                             uu___9 t1 in
                                         (match uu___8 with
                                          | (t3, uu___9, g) ->
                                              (FStarC_TypeChecker_Rel.force_trivial_guard
                                                 env1 g;
                                               t3)) in
                                   let uu___8 =
                                     FStarC_TypeChecker_Generalize.generalize_universes
                                       env1 t2 in
                                   (match uu___8 with
                                    | (g_us, t3) ->
                                        (if (FStarC_List.length g_us) <> n
                                         then
                                           (let error =
                                              let uu___10 =
                                                FStarC_Class_Show.show
                                                  FStarC_Class_Show.showable_int
                                                  n in
                                              let uu___11 =
                                                FStarC_Class_Show.show
                                                  FStarC_Class_Show.showable_nat
                                                  (FStarC_List.length g_us) in
                                              FStarC_Format.fmt4
                                                "Expected %s:%s to be universe-polymorphic in %s universes, found %s"
                                                (FStarC_Ident.string_of_lid
                                                   ed2.FStarC_Syntax_Syntax.mname)
                                                comb uu___10 uu___11 in
                                            FStarC_Errors.raise_error
                                              (FStarC_Syntax_Syntax.has_range_syntax
                                                 ()) t3
                                              FStarC_Errors_Codes.Fatal_MismatchUniversePolymorphic
                                              ()
                                              (Obj.magic
                                                 FStarC_Errors_Msg.is_error_message_string)
                                              (Obj.magic error))
                                         else ();
                                         (match us2 with
                                          | [] -> (g_us, t3)
                                          | uu___10 ->
                                              let uu___11 =
                                                if
                                                  (FStarC_List.length us2) =
                                                    (FStarC_List.length g_us)
                                                then
                                                  FStarC_List.forall2
                                                    (fun u1 u2 ->
                                                       (FStarC_Syntax_Syntax.order_univ_name
                                                          u1 u2)
                                                         = Prims.int_zero)
                                                    us2 g_us
                                                else false in
                                              if uu___11
                                              then (g_us, t3)
                                              else
                                                (let uu___12 =
                                                   let uu___13 =
                                                     FStarC_Class_Show.show
                                                       FStarC_Class_Show.showable_nat
                                                       (FStarC_List.length
                                                          us2) in
                                                   let uu___14 =
                                                     FStarC_Class_Show.show
                                                       FStarC_Class_Show.showable_nat
                                                       (FStarC_List.length
                                                          g_us) in
                                                   FStarC_Format.fmt4
                                                     "Expected and generalized universes in the declaration for %s:%s are different, expected: %s, but found %s"
                                                     (FStarC_Ident.string_of_lid
                                                        ed2.FStarC_Syntax_Syntax.mname)
                                                     comb uu___13 uu___14 in
                                                 FStarC_Errors.raise_error
                                                   (FStarC_Syntax_Syntax.has_range_syntax
                                                      ()) t3
                                                   FStarC_Errors_Codes.Fatal_UnexpectedNumberOfUniverse
                                                   ()
                                                   (Obj.magic
                                                      FStarC_Errors_Msg.is_error_message_string)
                                                   (Obj.magic uu___12)))))) in
                        let signature =
                          check_and_gen' "signature" Prims.int_one
                            FStar_Pervasives_Native.None
                            (FStarC_Syntax_Util.effect_sig_ts
                               ed2.FStarC_Syntax_Syntax.signature)
                            FStar_Pervasives_Native.None in
                        (let uu___7 = FStarC_Effect.op_Bang dbg in
                         if uu___7
                         then
                           let uu___8 =
                             FStarC_Syntax_Print.tscheme_to_string signature in
                           FStarC_Format.print1 "Typechecked signature: %s\n"
                             uu___8
                         else ());
                        (let fresh_a_and_wp uu___7 =
                           let fail t =
                             FStarC_TypeChecker_Err.unexpected_signature_for_monad
                               env
                               (FStar_Pervasives_Native.snd
                                  (FStarC_Syntax_Util.effect_sig_ts
                                     ed2.FStarC_Syntax_Syntax.signature)).FStarC_Syntax_Syntax.pos
                               ed2.FStarC_Syntax_Syntax.mname t in
                           let uu___8 =
                             FStarC_TypeChecker_Env.inst_tscheme signature in
                           match uu___8 with
                           | (uu___9, signature1) ->
                               let uu___10 =
                                 let uu___11 =
                                   FStarC_Syntax_Subst.compress signature1 in
                                 uu___11.FStarC_Syntax_Syntax.n in
                               (match uu___10 with
                                | FStarC_Syntax_Syntax.Tm_arrow
                                    { FStarC_Syntax_Syntax.bs1 = bs1;
                                      FStarC_Syntax_Syntax.comp = uu___11;_}
                                    ->
                                    let bs2 =
                                      FStarC_Syntax_Subst.open_binders bs1 in
                                    (match bs2 with
                                     | { FStarC_Syntax_Syntax.binder_bv = a;
                                         FStarC_Syntax_Syntax.binder_qual =
                                           uu___12;
                                         FStarC_Syntax_Syntax.binder_positivity
                                           = uu___13;
                                         FStarC_Syntax_Syntax.binder_attrs =
                                           uu___14;_}::{
                                                         FStarC_Syntax_Syntax.binder_bv
                                                           = wp;
                                                         FStarC_Syntax_Syntax.binder_qual
                                                           = uu___15;
                                                         FStarC_Syntax_Syntax.binder_positivity
                                                           = uu___16;
                                                         FStarC_Syntax_Syntax.binder_attrs
                                                           = uu___17;_}::[]
                                         ->
                                         (a, (wp.FStarC_Syntax_Syntax.sort))
                                     | uu___12 -> fail signature1)
                                | uu___11 -> fail signature1) in
                         let log_combinator s ts =
                           let uu___7 = FStarC_Effect.op_Bang dbg in
                           if uu___7
                           then
                             let uu___8 =
                               FStarC_Syntax_Print.tscheme_to_string ts in
                             FStarC_Format.print3 "Typechecked %s:%s = %s\n"
                               (FStarC_Ident.string_of_lid
                                  ed2.FStarC_Syntax_Syntax.mname) s uu___8
                           else () in
                         let ret_wp =
                           let uu___7 = fresh_a_and_wp () in
                           match uu___7 with
                           | (a, wp_sort) ->
                               let k =
                                 let uu___8 =
                                   let uu___9 =
                                     let uu___10 =
                                       let uu___11 =
                                         FStarC_Syntax_Syntax.bv_to_name a in
                                       FStarC_Syntax_Syntax.null_binder
                                         uu___11 in
                                     [uu___10] in
                                   (FStarC_Syntax_Syntax.mk_binder a) ::
                                     uu___9 in
                                 let uu___9 =
                                   FStarC_Syntax_Syntax.mk_GTotal wp_sort in
                                 FStarC_Syntax_Util.arrow uu___8 uu___9 in
                               check_and_gen' "ret_wp" Prims.int_one
                                 FStar_Pervasives_Native.None
                                 (FStarC_Syntax_Util.get_return_vc_combinator
                                    ed2) (FStar_Pervasives_Native.Some k) in
                         log_combinator "ret_wp" ret_wp;
                         (let bind_wp =
                            let uu___8 = fresh_a_and_wp () in
                            match uu___8 with
                            | (a, wp_sort_a) ->
                                let uu___9 = fresh_a_and_wp () in
                                (match uu___9 with
                                 | (b, wp_sort_b) ->
                                     let wp_sort_a_b =
                                       let uu___10 =
                                         let uu___11 =
                                           let uu___12 =
                                             FStarC_Syntax_Syntax.bv_to_name
                                               a in
                                           FStarC_Syntax_Syntax.null_binder
                                             uu___12 in
                                         [uu___11] in
                                       let uu___11 =
                                         FStarC_Syntax_Syntax.mk_Total
                                           wp_sort_b in
                                       FStarC_Syntax_Util.arrow uu___10
                                         uu___11 in
                                     let k =
                                       let uu___10 =
                                         let uu___11 =
                                           let uu___12 =
                                             let uu___13 =
                                               FStarC_Syntax_Syntax.null_binder
                                                 wp_sort_a in
                                             let uu___14 =
                                               let uu___15 =
                                                 FStarC_Syntax_Syntax.null_binder
                                                   wp_sort_a_b in
                                               [uu___15] in
                                             uu___13 :: uu___14 in
                                           (FStarC_Syntax_Syntax.mk_binder b)
                                             :: uu___12 in
                                         (FStarC_Syntax_Syntax.mk_binder a)
                                           :: uu___11 in
                                       let uu___11 =
                                         FStarC_Syntax_Syntax.mk_Total
                                           wp_sort_b in
                                       FStarC_Syntax_Util.arrow uu___10
                                         uu___11 in
                                     check_and_gen' "bind_wp"
                                       (Prims.of_int 2)
                                       FStar_Pervasives_Native.None
                                       (FStar_Pervasives_Native.fst
                                          (FStarC_Syntax_Util.get_bind_vc_combinator
                                             ed2))
                                       (FStar_Pervasives_Native.Some k)) in
                          log_combinator "bind_wp" bind_wp;
                          (let stronger =
                             let uu___9 = fresh_a_and_wp () in
                             match uu___9 with
                             | (a, wp_sort_a) ->
                                 let k =
                                   let uu___10 =
                                     let uu___11 =
                                       let uu___12 =
                                         FStarC_Syntax_Syntax.null_binder
                                           wp_sort_a in
                                       let uu___13 =
                                         let uu___14 =
                                           FStarC_Syntax_Syntax.null_binder
                                             wp_sort_a in
                                         [uu___14] in
                                       uu___12 :: uu___13 in
                                     (FStarC_Syntax_Syntax.mk_binder a) ::
                                       uu___11 in
                                   let uu___11 =
                                     FStarC_Syntax_Syntax.mk_Total
                                       FStarC_Syntax_Syntax.t_prop in
                                   FStarC_Syntax_Util.arrow uu___10 uu___11 in
                                 check_and_gen' "stronger" Prims.int_one
                                   FStar_Pervasives_Native.None
                                   (FStar_Pervasives_Native.fst
                                      (FStarC_Syntax_Util.get_stronger_vc_combinator
                                         ed2))
                                   (FStar_Pervasives_Native.Some k) in
                           log_combinator "stronger" stronger;
                           (let if_then_else =
                              let uu___10 = fresh_a_and_wp () in
                              match uu___10 with
                              | (a, wp_sort_a) ->
                                  let p =
                                    FStarC_Syntax_Syntax.new_bv
                                      (FStar_Pervasives_Native.Some
                                         (FStarC_Ident.range_of_lid
                                            ed2.FStarC_Syntax_Syntax.mname))
                                      FStarC_Syntax_Syntax.t_prop in
                                  let k =
                                    let uu___11 =
                                      let uu___12 =
                                        let uu___13 =
                                          let uu___14 =
                                            FStarC_Syntax_Syntax.null_binder
                                              wp_sort_a in
                                          let uu___15 =
                                            let uu___16 =
                                              FStarC_Syntax_Syntax.null_binder
                                                wp_sort_a in
                                            [uu___16] in
                                          uu___14 :: uu___15 in
                                        (FStarC_Syntax_Syntax.mk_binder p) ::
                                          uu___13 in
                                      (FStarC_Syntax_Syntax.mk_binder a) ::
                                        uu___12 in
                                    let uu___12 =
                                      FStarC_Syntax_Syntax.mk_Total wp_sort_a in
                                    FStarC_Syntax_Util.arrow uu___11 uu___12 in
                                  let uu___11 =
                                    FStarC_Option.must
                                      (FStarC_Syntax_Util.get_wp_if_then_else_combinator
                                         ed2) in
                                  check_and_gen' "if_then_else" Prims.int_one
                                    FStar_Pervasives_Native.None uu___11
                                    (FStar_Pervasives_Native.Some k) in
                            log_combinator "if_then_else" if_then_else;
                            (let ite_wp =
                               let uu___11 = fresh_a_and_wp () in
                               match uu___11 with
                               | (a, wp_sort_a) ->
                                   let k =
                                     let uu___12 =
                                       let uu___13 =
                                         let uu___14 =
                                           FStarC_Syntax_Syntax.null_binder
                                             wp_sort_a in
                                         [uu___14] in
                                       (FStarC_Syntax_Syntax.mk_binder a) ::
                                         uu___13 in
                                     let uu___13 =
                                       FStarC_Syntax_Syntax.mk_Total
                                         wp_sort_a in
                                     FStarC_Syntax_Util.arrow uu___12 uu___13 in
                                   let uu___12 =
                                     FStarC_Option.must
                                       (FStarC_Syntax_Util.get_wp_ite_combinator
                                          ed2) in
                                   check_and_gen' "ite_wp" Prims.int_one
                                     FStar_Pervasives_Native.None uu___12
                                     (FStar_Pervasives_Native.Some k) in
                             log_combinator "ite_wp" ite_wp;
                             (let close_wp =
                                let uu___12 = fresh_a_and_wp () in
                                match uu___12 with
                                | (a, wp_sort_a) ->
                                    let b =
                                      let uu___13 =
                                        let uu___14 =
                                          FStarC_Syntax_Util.type_u () in
                                        FStar_Pervasives_Native.fst uu___14 in
                                      FStarC_Syntax_Syntax.new_bv
                                        (FStar_Pervasives_Native.Some
                                           (FStarC_Ident.range_of_lid
                                              ed2.FStarC_Syntax_Syntax.mname))
                                        uu___13 in
                                    let wp_sort_b_a =
                                      let uu___13 =
                                        let uu___14 =
                                          let uu___15 =
                                            FStarC_Syntax_Syntax.bv_to_name b in
                                          FStarC_Syntax_Syntax.null_binder
                                            uu___15 in
                                        [uu___14] in
                                      let uu___14 =
                                        FStarC_Syntax_Syntax.mk_Total
                                          wp_sort_a in
                                      FStarC_Syntax_Util.arrow uu___13
                                        uu___14 in
                                    let k =
                                      let uu___13 =
                                        let uu___14 =
                                          let uu___15 =
                                            let uu___16 =
                                              FStarC_Syntax_Syntax.null_binder
                                                wp_sort_b_a in
                                            [uu___16] in
                                          (FStarC_Syntax_Syntax.mk_binder b)
                                            :: uu___15 in
                                        (FStarC_Syntax_Syntax.mk_binder a) ::
                                          uu___14 in
                                      let uu___14 =
                                        FStarC_Syntax_Syntax.mk_Total
                                          wp_sort_a in
                                      FStarC_Syntax_Util.arrow uu___13
                                        uu___14 in
                                    let uu___13 =
                                      FStarC_Option.must
                                        (FStarC_Syntax_Util.get_wp_close_combinator
                                           ed2) in
                                    check_and_gen' "close_wp"
                                      (Prims.of_int 2)
                                      FStar_Pervasives_Native.None uu___13
                                      (FStar_Pervasives_Native.Some k) in
                              log_combinator "close_wp" close_wp;
                              (let trivial =
                                 let uu___13 = fresh_a_and_wp () in
                                 match uu___13 with
                                 | (a, wp_sort_a) ->
                                     let k =
                                       let uu___14 =
                                         let uu___15 =
                                           let uu___16 =
                                             FStarC_Syntax_Syntax.null_binder
                                               wp_sort_a in
                                           [uu___16] in
                                         (FStarC_Syntax_Syntax.mk_binder a)
                                           :: uu___15 in
                                       let uu___15 =
                                         FStarC_Syntax_Syntax.mk_GTotal
                                           FStarC_Syntax_Syntax.t_prop in
                                       FStarC_Syntax_Util.arrow uu___14
                                         uu___15 in
                                     let trivial1 =
                                       let uu___14 =
                                         FStarC_Option.must
                                           (FStarC_Syntax_Util.get_wp_trivial_combinator
                                              ed2) in
                                       check_and_gen' "trivial" Prims.int_one
                                         FStar_Pervasives_Native.None uu___14
                                         (FStar_Pervasives_Native.Some k) in
                                     (log_combinator "trivial" trivial1;
                                      trivial1) in
                               let uu___13 =
                                 match FStarC_Syntax_Util.get_eff_repr ed2
                                 with
                                 | FStar_Pervasives_Native.None ->
                                     (FStar_Pervasives_Native.None,
                                       FStar_Pervasives_Native.None,
                                       FStar_Pervasives_Native.None,
                                       (ed2.FStarC_Syntax_Syntax.actions))
                                 | uu___14 ->
                                     let repr =
                                       let uu___15 = fresh_a_and_wp () in
                                       match uu___15 with
                                       | (a, wp_sort_a) ->
                                           let uu___16 =
                                             FStarC_Syntax_Util.type_u () in
                                           (match uu___16 with
                                            | (t, uu___17) ->
                                                let k =
                                                  let uu___18 =
                                                    let uu___19 =
                                                      let uu___20 =
                                                        FStarC_Syntax_Syntax.null_binder
                                                          wp_sort_a in
                                                      [uu___20] in
                                                    (FStarC_Syntax_Syntax.mk_binder
                                                       a)
                                                      :: uu___19 in
                                                  let uu___19 =
                                                    FStarC_Syntax_Syntax.mk_GTotal
                                                      t in
                                                  FStarC_Syntax_Util.arrow
                                                    uu___18 uu___19 in
                                                let uu___18 =
                                                  FStarC_Option.must
                                                    (FStarC_Syntax_Util.get_eff_repr
                                                       ed2) in
                                                check_and_gen' "repr"
                                                  Prims.int_one
                                                  FStar_Pervasives_Native.None
                                                  uu___18
                                                  (FStar_Pervasives_Native.Some
                                                     k)) in
                                     (log_combinator "repr" repr;
                                      (let mk_repr' t wp =
                                         let uu___16 =
                                           FStarC_TypeChecker_Env.inst_tscheme
                                             repr in
                                         match uu___16 with
                                         | (uu___17, repr1) ->
                                             let repr2 =
                                               FStarC_TypeChecker_Normalize.normalize
                                                 [FStarC_TypeChecker_Env.EraseUniverses;
                                                 FStarC_TypeChecker_Env.AllowUnboundUniverses]
                                                 env repr1 in
                                             FStarC_Syntax_Syntax.mk
                                               (FStarC_Syntax_Syntax.Tm_app
                                                  {
                                                    FStarC_Syntax_Syntax.hd =
                                                      repr2;
                                                    FStarC_Syntax_Syntax.args
                                                      =
                                                      [FStarC_Syntax_Syntax.as_arg
                                                         t;
                                                      FStarC_Syntax_Syntax.as_arg
                                                        wp]
                                                  })
                                               FStarC_Range_Type.dummyRange in
                                       let mk_repr a wp =
                                         let uu___16 =
                                           FStarC_Syntax_Syntax.bv_to_name a in
                                         mk_repr' uu___16 wp in
                                       let destruct_repr t =
                                         let uu___16 =
                                           let uu___17 =
                                             FStarC_Syntax_Subst.compress t in
                                           uu___17.FStarC_Syntax_Syntax.n in
                                         match uu___16 with
                                         | FStarC_Syntax_Syntax.Tm_app
                                             {
                                               FStarC_Syntax_Syntax.hd =
                                                 uu___17;
                                               FStarC_Syntax_Syntax.args =
                                                 (t1, uu___18)::(wp, uu___19)::[];_}
                                             -> (t1, wp)
                                         | uu___17 ->
                                             FStarC_Effect.failwith
                                               "Unexpected repr type" in
                                       let return_repr =
                                         let return_repr_ts =
                                           FStarC_Option.must
                                             (FStarC_Syntax_Util.get_return_repr
                                                ed2) in
                                         let uu___16 = fresh_a_and_wp () in
                                         match uu___16 with
                                         | (a, uu___17) ->
                                             let x_a =
                                               let uu___18 =
                                                 FStarC_Syntax_Syntax.bv_to_name
                                                   a in
                                               FStarC_Syntax_Syntax.gen_bv
                                                 "x_a"
                                                 FStar_Pervasives_Native.None
                                                 uu___18 in
                                             let res =
                                               let wp =
                                                 let uu___18 =
                                                   let uu___19 =
                                                     FStarC_TypeChecker_Env.inst_tscheme
                                                       ret_wp in
                                                   FStar_Pervasives_Native.snd
                                                     uu___19 in
                                                 let uu___19 =
                                                   let uu___20 =
                                                     let uu___21 =
                                                       FStarC_Syntax_Syntax.bv_to_name
                                                         a in
                                                     FStarC_Syntax_Syntax.as_arg
                                                       uu___21 in
                                                   let uu___21 =
                                                     let uu___22 =
                                                       let uu___23 =
                                                         FStarC_Syntax_Syntax.bv_to_name
                                                           x_a in
                                                       FStarC_Syntax_Syntax.as_arg
                                                         uu___23 in
                                                     [uu___22] in
                                                   uu___20 :: uu___21 in
                                                 FStarC_Syntax_Syntax.mk_Tm_app
                                                   uu___18 uu___19
                                                   FStarC_Range_Type.dummyRange in
                                               mk_repr a wp in
                                             let k =
                                               let uu___18 =
                                                 FStarC_Syntax_Syntax.mk_Total
                                                   res in
                                               FStarC_Syntax_Util.arrow
                                                 [FStarC_Syntax_Syntax.mk_binder
                                                    a;
                                                 FStarC_Syntax_Syntax.mk_binder
                                                   x_a] uu___18 in
                                             let uu___18 =
                                               FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term
                                                 env k in
                                             (match uu___18 with
                                              | (k1, uu___19, uu___20) ->
                                                  let env1 =
                                                    FStar_Pervasives_Native.Some
                                                      (FStarC_TypeChecker_Env.set_range
                                                         env
                                                         (FStar_Pervasives_Native.snd
                                                            return_repr_ts).FStarC_Syntax_Syntax.pos) in
                                                  check_and_gen'
                                                    "return_repr"
                                                    Prims.int_one env1
                                                    return_repr_ts
                                                    (FStar_Pervasives_Native.Some
                                                       k1)) in
                                       log_combinator "return_repr"
                                         return_repr;
                                       (let bind_repr =
                                          let bind_repr_ts =
                                            FStarC_Option.must
                                              (FStarC_Syntax_Util.get_bind_repr
                                                 ed2) in
                                          let uu___17 = fresh_a_and_wp () in
                                          match uu___17 with
                                          | (a, wp_sort_a) ->
                                              let uu___18 = fresh_a_and_wp () in
                                              (match uu___18 with
                                               | (b, wp_sort_b) ->
                                                   let wp_sort_a_b =
                                                     let uu___19 =
                                                       let uu___20 =
                                                         let uu___21 =
                                                           FStarC_Syntax_Syntax.bv_to_name
                                                             a in
                                                         FStarC_Syntax_Syntax.null_binder
                                                           uu___21 in
                                                       [uu___20] in
                                                     let uu___20 =
                                                       FStarC_Syntax_Syntax.mk_Total
                                                         wp_sort_b in
                                                     FStarC_Syntax_Util.arrow
                                                       uu___19 uu___20 in
                                                   let wp_f =
                                                     FStarC_Syntax_Syntax.gen_bv
                                                       "wp_f"
                                                       FStar_Pervasives_Native.None
                                                       wp_sort_a in
                                                   let wp_g =
                                                     FStarC_Syntax_Syntax.gen_bv
                                                       "wp_g"
                                                       FStar_Pervasives_Native.None
                                                       wp_sort_a_b in
                                                   let x_a =
                                                     let uu___19 =
                                                       FStarC_Syntax_Syntax.bv_to_name
                                                         a in
                                                     FStarC_Syntax_Syntax.gen_bv
                                                       "x_a"
                                                       FStar_Pervasives_Native.None
                                                       uu___19 in
                                                   let wp_g_x =
                                                     let uu___19 =
                                                       FStarC_Syntax_Syntax.bv_to_name
                                                         wp_g in
                                                     let uu___20 =
                                                       let uu___21 =
                                                         let uu___22 =
                                                           FStarC_Syntax_Syntax.bv_to_name
                                                             x_a in
                                                         FStarC_Syntax_Syntax.as_arg
                                                           uu___22 in
                                                       [uu___21] in
                                                     FStarC_Syntax_Syntax.mk_Tm_app
                                                       uu___19 uu___20
                                                       FStarC_Range_Type.dummyRange in
                                                   let res =
                                                     let wp =
                                                       let uu___19 =
                                                         let uu___20 =
                                                           FStarC_TypeChecker_Env.inst_tscheme
                                                             bind_wp in
                                                         FStar_Pervasives_Native.snd
                                                           uu___20 in
                                                       let uu___20 =
                                                         let uu___21 =
                                                           let uu___22 =
                                                             FStarC_Syntax_Syntax.bv_to_name
                                                               a in
                                                           let uu___23 =
                                                             let uu___24 =
                                                               FStarC_Syntax_Syntax.bv_to_name
                                                                 b in
                                                             let uu___25 =
                                                               let uu___26 =
                                                                 FStarC_Syntax_Syntax.bv_to_name
                                                                   wp_f in
                                                               let uu___27 =
                                                                 let uu___28
                                                                   =
                                                                   FStarC_Syntax_Syntax.bv_to_name
                                                                    wp_g in
                                                                 [uu___28] in
                                                               uu___26 ::
                                                                 uu___27 in
                                                             uu___24 ::
                                                               uu___25 in
                                                           uu___22 :: uu___23 in
                                                         FStarC_List.map
                                                           FStarC_Syntax_Syntax.as_arg
                                                           uu___21 in
                                                       FStarC_Syntax_Syntax.mk_Tm_app
                                                         uu___19 uu___20
                                                         FStarC_Range_Type.dummyRange in
                                                     mk_repr b wp in
                                                   let maybe_range_arg = [] in
                                                   let k =
                                                     let uu___19 =
                                                       let uu___20 =
                                                         let uu___21 =
                                                           let uu___22 =
                                                             let uu___23 =
                                                               let uu___24 =
                                                                 let uu___25
                                                                   =
                                                                   FStarC_Syntax_Syntax.bv_to_name
                                                                    wp_f in
                                                                 mk_repr a
                                                                   uu___25 in
                                                               FStarC_Syntax_Syntax.null_binder
                                                                 uu___24 in
                                                             let uu___24 =
                                                               let uu___25 =
                                                                 let uu___26
                                                                   =
                                                                   let uu___27
                                                                    =
                                                                    let uu___28
                                                                    =
                                                                    let uu___29
                                                                    =
                                                                    mk_repr b
                                                                    wp_g_x in
                                                                    FStarC_Syntax_Syntax.mk_Total
                                                                    uu___29 in
                                                                    FStarC_Syntax_Util.arrow
                                                                    [
                                                                    FStarC_Syntax_Syntax.mk_binder
                                                                    x_a]
                                                                    uu___28 in
                                                                   FStarC_Syntax_Syntax.null_binder
                                                                    uu___27 in
                                                                 [uu___26] in
                                                               (FStarC_Syntax_Syntax.mk_binder
                                                                  wp_g)
                                                                 :: uu___25 in
                                                             uu___23 ::
                                                               uu___24 in
                                                           (FStarC_Syntax_Syntax.mk_binder
                                                              wp_f)
                                                             :: uu___22 in
                                                         FStarC_List.op_At
                                                           maybe_range_arg
                                                           uu___21 in
                                                       FStarC_List.op_At
                                                         [FStarC_Syntax_Syntax.mk_binder
                                                            a;
                                                         FStarC_Syntax_Syntax.mk_binder
                                                           b] uu___20 in
                                                     let uu___20 =
                                                       FStarC_Syntax_Syntax.mk_Total
                                                         res in
                                                     FStarC_Syntax_Util.arrow
                                                       uu___19 uu___20 in
                                                   let uu___19 =
                                                     FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term
                                                       env k in
                                                   (match uu___19 with
                                                    | (k1, uu___20, uu___21)
                                                        ->
                                                        let env1 =
                                                          FStarC_TypeChecker_Env.set_range
                                                            env
                                                            (FStar_Pervasives_Native.snd
                                                               bind_repr_ts).FStarC_Syntax_Syntax.pos in
                                                        let env2 =
                                                          FStar_Pervasives_Native.Some
                                                            {
                                                              FStarC_TypeChecker_Env.solver
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.solver);
                                                              FStarC_TypeChecker_Env.range
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.range);
                                                              FStarC_TypeChecker_Env.curmodule
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.curmodule);
                                                              FStarC_TypeChecker_Env.gamma
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.gamma);
                                                              FStarC_TypeChecker_Env.gamma_sig
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.gamma_sig);
                                                              FStarC_TypeChecker_Env.gamma_cache
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.gamma_cache);
                                                              FStarC_TypeChecker_Env.modules
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.modules);
                                                              FStarC_TypeChecker_Env.expected_typ
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.expected_typ);
                                                              FStarC_TypeChecker_Env.sigtab
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.sigtab);
                                                              FStarC_TypeChecker_Env.attrtab
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.attrtab);
                                                              FStarC_TypeChecker_Env.instantiate_imp
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.instantiate_imp);
                                                              FStarC_TypeChecker_Env.effects
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.effects);
                                                              FStarC_TypeChecker_Env.generalize
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.generalize);
                                                              FStarC_TypeChecker_Env.letrecs
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.letrecs);
                                                              FStarC_TypeChecker_Env.top_level
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.top_level);
                                                              FStarC_TypeChecker_Env.check_uvars
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.check_uvars);
                                                              FStarC_TypeChecker_Env.use_eq_strict
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.use_eq_strict);
                                                              FStarC_TypeChecker_Env.is_iface
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.is_iface);
                                                              FStarC_TypeChecker_Env.admit
                                                                = true;
                                                              FStarC_TypeChecker_Env.phase1
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.phase1);
                                                              FStarC_TypeChecker_Env.failhard
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.failhard);
                                                              FStarC_TypeChecker_Env.flychecking
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.flychecking);
                                                              FStarC_TypeChecker_Env.uvar_subtyping
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.uvar_subtyping);
                                                              FStarC_TypeChecker_Env.intactics
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.intactics);
                                                              FStarC_TypeChecker_Env.nocoerce
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.nocoerce);
                                                              FStarC_TypeChecker_Env.tc_term
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.tc_term);
                                                              FStarC_TypeChecker_Env.typeof_tot_or_gtot_term
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.typeof_tot_or_gtot_term);
                                                              FStarC_TypeChecker_Env.universe_of
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.universe_of);
                                                              FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term);
                                                              FStarC_TypeChecker_Env.teq_nosmt_force
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.teq_nosmt_force);
                                                              FStarC_TypeChecker_Env.subtype_nosmt_force
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.subtype_nosmt_force);
                                                              FStarC_TypeChecker_Env.qtbl_name_and_index
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.qtbl_name_and_index);
                                                              FStarC_TypeChecker_Env.normalized_eff_names
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.normalized_eff_names);
                                                              FStarC_TypeChecker_Env.fv_delta_depths
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.fv_delta_depths);
                                                              FStarC_TypeChecker_Env.proof_ns
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.proof_ns);
                                                              FStarC_TypeChecker_Env.synth_hook
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.synth_hook);
                                                              FStarC_TypeChecker_Env.try_solve_implicits_hook
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.try_solve_implicits_hook);
                                                              FStarC_TypeChecker_Env.splice
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.splice);
                                                              FStarC_TypeChecker_Env.mpreprocess
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.mpreprocess);
                                                              FStarC_TypeChecker_Env.postprocess
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.postprocess);
                                                              FStarC_TypeChecker_Env.identifier_info
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.identifier_info);
                                                              FStarC_TypeChecker_Env.tc_hooks
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.tc_hooks);
                                                              FStarC_TypeChecker_Env.dsenv
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.dsenv);
                                                              FStarC_TypeChecker_Env.nbe
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.nbe);
                                                              FStarC_TypeChecker_Env.strict_args_tab
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.strict_args_tab);
                                                              FStarC_TypeChecker_Env.erasable_types_tab
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.erasable_types_tab);
                                                              FStarC_TypeChecker_Env.enable_defer_to_tac
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.enable_defer_to_tac);
                                                              FStarC_TypeChecker_Env.unif_allow_ref_guards
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.unif_allow_ref_guards);
                                                              FStarC_TypeChecker_Env.erase_erasable_args
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.erase_erasable_args);
                                                              FStarC_TypeChecker_Env.core_check
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.core_check);
                                                              FStarC_TypeChecker_Env.missing_decl
                                                                =
                                                                (env1.FStarC_TypeChecker_Env.missing_decl)
                                                            } in
                                                        check_and_gen'
                                                          "bind_repr"
                                                          (Prims.of_int 2)
                                                          env2 bind_repr_ts
                                                          (FStar_Pervasives_Native.Some
                                                             k1))) in
                                        log_combinator "bind_repr" bind_repr;
                                        (let actions =
                                           let check_action act =
                                             if
                                               (FStarC_List.length
                                                  act.FStarC_Syntax_Syntax.action_params)
                                                 <> Prims.int_zero
                                             then
                                               FStarC_Effect.failwith
                                                 "tc_eff_decl: expected action_params to be empty"
                                             else ();
                                             (let uu___19 =
                                                if
                                                  act.FStarC_Syntax_Syntax.action_univs
                                                    = []
                                                then (env, act)
                                                else
                                                  (let uu___20 =
                                                     FStarC_Syntax_Subst.univ_var_opening
                                                       act.FStarC_Syntax_Syntax.action_univs in
                                                   match uu___20 with
                                                   | (usubst, uvs) ->
                                                       let uu___21 =
                                                         FStarC_TypeChecker_Env.push_univ_vars
                                                           env uvs in
                                                       let uu___22 =
                                                         let uu___23 =
                                                           FStarC_Syntax_Subst.subst
                                                             usubst
                                                             act.FStarC_Syntax_Syntax.action_defn in
                                                         let uu___24 =
                                                           FStarC_Syntax_Subst.subst
                                                             usubst
                                                             act.FStarC_Syntax_Syntax.action_typ in
                                                         {
                                                           FStarC_Syntax_Syntax.action_name
                                                             =
                                                             (act.FStarC_Syntax_Syntax.action_name);
                                                           FStarC_Syntax_Syntax.action_unqualified_name
                                                             =
                                                             (act.FStarC_Syntax_Syntax.action_unqualified_name);
                                                           FStarC_Syntax_Syntax.action_univs
                                                             = uvs;
                                                           FStarC_Syntax_Syntax.action_params
                                                             =
                                                             (act.FStarC_Syntax_Syntax.action_params);
                                                           FStarC_Syntax_Syntax.action_defn
                                                             = uu___23;
                                                           FStarC_Syntax_Syntax.action_typ
                                                             = uu___24
                                                         } in
                                                       (uu___21, uu___22)) in
                                              match uu___19 with
                                              | (env1, act1) ->
                                                  let act_typ =
                                                    let uu___20 =
                                                      let uu___21 =
                                                        FStarC_Syntax_Subst.compress
                                                          act1.FStarC_Syntax_Syntax.action_typ in
                                                      uu___21.FStarC_Syntax_Syntax.n in
                                                    match uu___20 with
                                                    | FStarC_Syntax_Syntax.Tm_arrow
                                                        {
                                                          FStarC_Syntax_Syntax.bs1
                                                            = bs1;
                                                          FStarC_Syntax_Syntax.comp
                                                            = c;_}
                                                        ->
                                                        let c1 =
                                                          FStarC_TypeChecker_Env.comp_to_comp_typ
                                                            env1 c in
                                                        if
                                                          FStarC_Ident.lid_equals
                                                            c1.FStarC_Syntax_Syntax.effect_name
                                                            ed2.FStarC_Syntax_Syntax.mname
                                                        then
                                                          let uu___21 =
                                                            let uu___22 =
                                                              mk_repr'
                                                                c1.FStarC_Syntax_Syntax.result_typ
                                                                (FStar_Pervasives_Native.fst
                                                                   (FStarC_List.hd
                                                                    c1.FStarC_Syntax_Syntax.effect_args)) in
                                                            FStarC_Syntax_Syntax.mk_Total
                                                              uu___22 in
                                                          FStarC_Syntax_Util.arrow
                                                            bs1 uu___21
                                                        else
                                                          act1.FStarC_Syntax_Syntax.action_typ
                                                    | uu___21 ->
                                                        act1.FStarC_Syntax_Syntax.action_typ in
                                                  let uu___20 =
                                                    FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term
                                                      env1 act_typ in
                                                  (match uu___20 with
                                                   | (act_typ1, uu___21, g_t)
                                                       ->
                                                       let env' =
                                                         let uu___22 =
                                                           FStarC_TypeChecker_Env.set_expected_typ
                                                             env1 act_typ1 in
                                                         {
                                                           FStarC_TypeChecker_Env.solver
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.solver);
                                                           FStarC_TypeChecker_Env.range
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.range);
                                                           FStarC_TypeChecker_Env.curmodule
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.curmodule);
                                                           FStarC_TypeChecker_Env.gamma
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.gamma);
                                                           FStarC_TypeChecker_Env.gamma_sig
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.gamma_sig);
                                                           FStarC_TypeChecker_Env.gamma_cache
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.gamma_cache);
                                                           FStarC_TypeChecker_Env.modules
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.modules);
                                                           FStarC_TypeChecker_Env.expected_typ
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.expected_typ);
                                                           FStarC_TypeChecker_Env.sigtab
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.sigtab);
                                                           FStarC_TypeChecker_Env.attrtab
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.attrtab);
                                                           FStarC_TypeChecker_Env.instantiate_imp
                                                             = false;
                                                           FStarC_TypeChecker_Env.effects
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.effects);
                                                           FStarC_TypeChecker_Env.generalize
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.generalize);
                                                           FStarC_TypeChecker_Env.letrecs
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.letrecs);
                                                           FStarC_TypeChecker_Env.top_level
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.top_level);
                                                           FStarC_TypeChecker_Env.check_uvars
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.check_uvars);
                                                           FStarC_TypeChecker_Env.use_eq_strict
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.use_eq_strict);
                                                           FStarC_TypeChecker_Env.is_iface
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.is_iface);
                                                           FStarC_TypeChecker_Env.admit
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.admit);
                                                           FStarC_TypeChecker_Env.phase1
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.phase1);
                                                           FStarC_TypeChecker_Env.failhard
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.failhard);
                                                           FStarC_TypeChecker_Env.flychecking
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.flychecking);
                                                           FStarC_TypeChecker_Env.uvar_subtyping
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.uvar_subtyping);
                                                           FStarC_TypeChecker_Env.intactics
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.intactics);
                                                           FStarC_TypeChecker_Env.nocoerce
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.nocoerce);
                                                           FStarC_TypeChecker_Env.tc_term
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.tc_term);
                                                           FStarC_TypeChecker_Env.typeof_tot_or_gtot_term
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.typeof_tot_or_gtot_term);
                                                           FStarC_TypeChecker_Env.universe_of
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.universe_of);
                                                           FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term);
                                                           FStarC_TypeChecker_Env.teq_nosmt_force
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.teq_nosmt_force);
                                                           FStarC_TypeChecker_Env.subtype_nosmt_force
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.subtype_nosmt_force);
                                                           FStarC_TypeChecker_Env.qtbl_name_and_index
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.qtbl_name_and_index);
                                                           FStarC_TypeChecker_Env.normalized_eff_names
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.normalized_eff_names);
                                                           FStarC_TypeChecker_Env.fv_delta_depths
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.fv_delta_depths);
                                                           FStarC_TypeChecker_Env.proof_ns
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.proof_ns);
                                                           FStarC_TypeChecker_Env.synth_hook
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.synth_hook);
                                                           FStarC_TypeChecker_Env.try_solve_implicits_hook
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.try_solve_implicits_hook);
                                                           FStarC_TypeChecker_Env.splice
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.splice);
                                                           FStarC_TypeChecker_Env.mpreprocess
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.mpreprocess);
                                                           FStarC_TypeChecker_Env.postprocess
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.postprocess);
                                                           FStarC_TypeChecker_Env.identifier_info
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.identifier_info);
                                                           FStarC_TypeChecker_Env.tc_hooks
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.tc_hooks);
                                                           FStarC_TypeChecker_Env.dsenv
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.dsenv);
                                                           FStarC_TypeChecker_Env.nbe
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.nbe);
                                                           FStarC_TypeChecker_Env.strict_args_tab
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.strict_args_tab);
                                                           FStarC_TypeChecker_Env.erasable_types_tab
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.erasable_types_tab);
                                                           FStarC_TypeChecker_Env.enable_defer_to_tac
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.enable_defer_to_tac);
                                                           FStarC_TypeChecker_Env.unif_allow_ref_guards
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.unif_allow_ref_guards);
                                                           FStarC_TypeChecker_Env.erase_erasable_args
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.erase_erasable_args);
                                                           FStarC_TypeChecker_Env.core_check
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.core_check);
                                                           FStarC_TypeChecker_Env.missing_decl
                                                             =
                                                             (uu___22.FStarC_TypeChecker_Env.missing_decl)
                                                         } in
                                                       ((let uu___23 =
                                                           FStarC_Effect.op_Bang
                                                             dbg in
                                                         if uu___23
                                                         then
                                                           let uu___24 =
                                                             FStarC_Class_Show.show
                                                               FStarC_Syntax_Print.showable_term
                                                               act1.FStarC_Syntax_Syntax.action_defn in
                                                           let uu___25 =
                                                             FStarC_Class_Show.show
                                                               FStarC_Syntax_Print.showable_term
                                                               act_typ1 in
                                                           FStarC_Format.print3
                                                             "Checking action %s:\n[definition]: %s\n[cps'd type]: %s\n"
                                                             (FStarC_Ident.string_of_lid
                                                                act1.FStarC_Syntax_Syntax.action_name)
                                                             uu___24 uu___25
                                                         else ());
                                                        (let uu___23 =
                                                           FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term
                                                             env'
                                                             act1.FStarC_Syntax_Syntax.action_defn in
                                                         match uu___23 with
                                                         | (act_defn,
                                                            uu___24, g_a) ->
                                                             ((let uu___26 =
                                                                 FStarC_TypeChecker_Env.conj_guards
                                                                   [g_a; g_t] in
                                                               FStarC_TypeChecker_Rel.force_trivial_guard
                                                                 env1 uu___26);
                                                              (let act_defn1
                                                                 =
                                                                 FStarC_TypeChecker_Normalize.normalize
                                                                   [FStarC_TypeChecker_Env.UnfoldUntil
                                                                    FStarC_Syntax_Syntax.delta_constant]
                                                                   env1
                                                                   act_defn in
                                                               let act_typ2 =
                                                                 FStarC_TypeChecker_Normalize.normalize
                                                                   [FStarC_TypeChecker_Env.UnfoldUntil
                                                                    FStarC_Syntax_Syntax.delta_constant;
                                                                   FStarC_TypeChecker_Env.Eager_unfolding;
                                                                   FStarC_TypeChecker_Env.Beta]
                                                                   env1
                                                                   act_typ1 in
                                                               let uu___26 =
                                                                 let act_typ3
                                                                   =
                                                                   FStarC_Syntax_Subst.compress
                                                                    act_typ2 in
                                                                 match 
                                                                   act_typ3.FStarC_Syntax_Syntax.n
                                                                 with
                                                                 | FStarC_Syntax_Syntax.Tm_arrow
                                                                    {
                                                                    FStarC_Syntax_Syntax.bs1
                                                                    = bs1;
                                                                    FStarC_Syntax_Syntax.comp
                                                                    = c;_} ->
                                                                    let uu___27
                                                                    =
                                                                    FStarC_Syntax_Subst.open_comp
                                                                    bs1 c in
                                                                    (match uu___27
                                                                    with
                                                                    | 
                                                                    (bs2,
                                                                    uu___28)
                                                                    ->
                                                                    let res =
                                                                    mk_repr'
                                                                    FStarC_Syntax_Syntax.tun
                                                                    FStarC_Syntax_Syntax.tun in
                                                                    let k =
                                                                    let uu___29
                                                                    =
                                                                    FStarC_Syntax_Syntax.mk_Total
                                                                    res in
                                                                    FStarC_Syntax_Util.arrow
                                                                    bs2
                                                                    uu___29 in
                                                                    let uu___29
                                                                    =
                                                                    FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term
                                                                    env1 k in
                                                                    (match uu___29
                                                                    with
                                                                    | 
                                                                    (k1,
                                                                    uu___30,
                                                                    g) ->
                                                                    (k1, g)))
                                                                 | uu___27 ->
                                                                    let uu___28
                                                                    =
                                                                    let uu___29
                                                                    =
                                                                    FStarC_Class_Show.show
                                                                    FStarC_Syntax_Print.showable_term
                                                                    act_typ3 in
                                                                    let uu___30
                                                                    =
                                                                    FStarC_Class_Tagged.tag_of
                                                                    FStarC_Syntax_Syntax.tagged_term
                                                                    act_typ3 in
                                                                    FStarC_Format.fmt2
                                                                    "Actions must have function types (not: %s, a.k.a. %s)"
                                                                    uu___29
                                                                    uu___30 in
                                                                    FStarC_Errors.raise_error
                                                                    (FStarC_Syntax_Syntax.has_range_syntax
                                                                    ())
                                                                    act_defn1
                                                                    FStarC_Errors_Codes.Fatal_ActionMustHaveFunctionType
                                                                    ()
                                                                    (Obj.magic
                                                                    FStarC_Errors_Msg.is_error_message_string)
                                                                    (Obj.magic
                                                                    uu___28) in
                                                               match uu___26
                                                               with
                                                               | (expected_k,
                                                                  g_k) ->
                                                                   ((
                                                                    let g =
                                                                    FStarC_TypeChecker_Rel.teq
                                                                    env1
                                                                    act_typ2
                                                                    expected_k in
                                                                    let g1 =
                                                                    FStarC_TypeChecker_Env.conj_guard
                                                                    g g_k in
                                                                    match 
                                                                    g1.FStarC_TypeChecker_Common.guard_f
                                                                    with
                                                                    | 
                                                                    FStarC_TypeChecker_Common.NonTrivial
                                                                    uu___28
                                                                    ->
                                                                    let uu___29
                                                                    =
                                                                    let uu___30
                                                                    =
                                                                    FStarC_Class_Show.show
                                                                    FStarC_Syntax_Print.showable_term
                                                                    act_typ2 in
                                                                    FStarC_Format.fmt1
                                                                    "Unexpected non trivial guard formula when checking action type shape (%s)"
                                                                    uu___30 in
                                                                    FStarC_Errors.raise_error
                                                                    (FStarC_Syntax_Syntax.has_range_syntax
                                                                    ())
                                                                    act_defn1
                                                                    FStarC_Errors_Codes.Fatal_ActionMustHaveFunctionType
                                                                    ()
                                                                    (Obj.magic
                                                                    FStarC_Errors_Msg.is_error_message_string)
                                                                    (Obj.magic
                                                                    uu___29)
                                                                    | 
                                                                    FStarC_TypeChecker_Common.Trivial
                                                                    ->
                                                                    let uu___28
                                                                    =
                                                                    FStarC_TypeChecker_Env.conj_guards
                                                                    [g_k; g1] in
                                                                    FStarC_TypeChecker_Rel.force_trivial_guard
                                                                    {
                                                                    FStarC_TypeChecker_Env.solver
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.solver);
                                                                    FStarC_TypeChecker_Env.range
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.range);
                                                                    FStarC_TypeChecker_Env.curmodule
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.curmodule);
                                                                    FStarC_TypeChecker_Env.gamma
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.gamma);
                                                                    FStarC_TypeChecker_Env.gamma_sig
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.gamma_sig);
                                                                    FStarC_TypeChecker_Env.gamma_cache
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.gamma_cache);
                                                                    FStarC_TypeChecker_Env.modules
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.modules);
                                                                    FStarC_TypeChecker_Env.expected_typ
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.expected_typ);
                                                                    FStarC_TypeChecker_Env.sigtab
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.sigtab);
                                                                    FStarC_TypeChecker_Env.attrtab
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.attrtab);
                                                                    FStarC_TypeChecker_Env.instantiate_imp
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.instantiate_imp);
                                                                    FStarC_TypeChecker_Env.effects
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.effects);
                                                                    FStarC_TypeChecker_Env.generalize
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.generalize);
                                                                    FStarC_TypeChecker_Env.letrecs
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.letrecs);
                                                                    FStarC_TypeChecker_Env.top_level
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.top_level);
                                                                    FStarC_TypeChecker_Env.check_uvars
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.check_uvars);
                                                                    FStarC_TypeChecker_Env.use_eq_strict
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.use_eq_strict);
                                                                    FStarC_TypeChecker_Env.is_iface
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.is_iface);
                                                                    FStarC_TypeChecker_Env.admit
                                                                    = true;
                                                                    FStarC_TypeChecker_Env.phase1
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.phase1);
                                                                    FStarC_TypeChecker_Env.failhard
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.failhard);
                                                                    FStarC_TypeChecker_Env.flychecking
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.flychecking);
                                                                    FStarC_TypeChecker_Env.uvar_subtyping
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.uvar_subtyping);
                                                                    FStarC_TypeChecker_Env.intactics
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.intactics);
                                                                    FStarC_TypeChecker_Env.nocoerce
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.nocoerce);
                                                                    FStarC_TypeChecker_Env.tc_term
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.tc_term);
                                                                    FStarC_TypeChecker_Env.typeof_tot_or_gtot_term
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.typeof_tot_or_gtot_term);
                                                                    FStarC_TypeChecker_Env.universe_of
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.universe_of);
                                                                    FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term);
                                                                    FStarC_TypeChecker_Env.teq_nosmt_force
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.teq_nosmt_force);
                                                                    FStarC_TypeChecker_Env.subtype_nosmt_force
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.subtype_nosmt_force);
                                                                    FStarC_TypeChecker_Env.qtbl_name_and_index
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.qtbl_name_and_index);
                                                                    FStarC_TypeChecker_Env.normalized_eff_names
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.normalized_eff_names);
                                                                    FStarC_TypeChecker_Env.fv_delta_depths
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.fv_delta_depths);
                                                                    FStarC_TypeChecker_Env.proof_ns
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.proof_ns);
                                                                    FStarC_TypeChecker_Env.synth_hook
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.synth_hook);
                                                                    FStarC_TypeChecker_Env.try_solve_implicits_hook
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.try_solve_implicits_hook);
                                                                    FStarC_TypeChecker_Env.splice
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.splice);
                                                                    FStarC_TypeChecker_Env.mpreprocess
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.mpreprocess);
                                                                    FStarC_TypeChecker_Env.postprocess
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.postprocess);
                                                                    FStarC_TypeChecker_Env.identifier_info
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.identifier_info);
                                                                    FStarC_TypeChecker_Env.tc_hooks
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.tc_hooks);
                                                                    FStarC_TypeChecker_Env.dsenv
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.dsenv);
                                                                    FStarC_TypeChecker_Env.nbe
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.nbe);
                                                                    FStarC_TypeChecker_Env.strict_args_tab
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.strict_args_tab);
                                                                    FStarC_TypeChecker_Env.erasable_types_tab
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.erasable_types_tab);
                                                                    FStarC_TypeChecker_Env.enable_defer_to_tac
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.enable_defer_to_tac);
                                                                    FStarC_TypeChecker_Env.unif_allow_ref_guards
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.unif_allow_ref_guards);
                                                                    FStarC_TypeChecker_Env.erase_erasable_args
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.erase_erasable_args);
                                                                    FStarC_TypeChecker_Env.core_check
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.core_check);
                                                                    FStarC_TypeChecker_Env.missing_decl
                                                                    =
                                                                    (env1.FStarC_TypeChecker_Env.missing_decl)
                                                                    } uu___28);
                                                                    (
                                                                    let act_typ3
                                                                    =
                                                                    let uu___28
                                                                    =
                                                                    let uu___29
                                                                    =
                                                                    FStarC_Syntax_Subst.compress
                                                                    expected_k in
                                                                    uu___29.FStarC_Syntax_Syntax.n in
                                                                    match uu___28
                                                                    with
                                                                    | 
                                                                    FStarC_Syntax_Syntax.Tm_arrow
                                                                    {
                                                                    FStarC_Syntax_Syntax.bs1
                                                                    = bs1;
                                                                    FStarC_Syntax_Syntax.comp
                                                                    = c;_} ->
                                                                    let uu___29
                                                                    =
                                                                    FStarC_Syntax_Subst.open_comp
                                                                    bs1 c in
                                                                    (match uu___29
                                                                    with
                                                                    | 
                                                                    (bs2, c1)
                                                                    ->
                                                                    let uu___30
                                                                    =
                                                                    destruct_repr
                                                                    (FStarC_Syntax_Util.comp_result
                                                                    c1) in
                                                                    (match uu___30
                                                                    with
                                                                    | 
                                                                    (a, wp)
                                                                    ->
                                                                    let c2 =
                                                                    let uu___31
                                                                    =
                                                                    let uu___32
                                                                    =
                                                                    let uu___33
                                                                    =
                                                                    FStarC_TypeChecker_Env.push_binders
                                                                    env1 bs2 in
                                                                    env1.FStarC_TypeChecker_Env.universe_of
                                                                    uu___33 a in
                                                                    [uu___32] in
                                                                    {
                                                                    FStarC_Syntax_Syntax.comp_univs
                                                                    = uu___31;
                                                                    FStarC_Syntax_Syntax.effect_name
                                                                    =
                                                                    (ed2.FStarC_Syntax_Syntax.mname);
                                                                    FStarC_Syntax_Syntax.result_typ
                                                                    = a;
                                                                    FStarC_Syntax_Syntax.effect_args
                                                                    =
                                                                    [
                                                                    FStarC_Syntax_Syntax.as_arg
                                                                    wp];
                                                                    FStarC_Syntax_Syntax.flags
                                                                    = []
                                                                    } in
                                                                    let uu___31
                                                                    =
                                                                    FStarC_Syntax_Syntax.mk_Comp
                                                                    c2 in
                                                                    FStarC_Syntax_Util.arrow
                                                                    bs2
                                                                    uu___31))
                                                                    | 
                                                                    uu___29
                                                                    ->
                                                                    FStarC_Effect.failwith
                                                                    "Impossible (expected_k is an arrow)" in
                                                                    let uu___28
                                                                    =
                                                                    if
                                                                    act1.FStarC_Syntax_Syntax.action_univs
                                                                    = []
                                                                    then
                                                                    FStarC_TypeChecker_Generalize.generalize_universes
                                                                    env1
                                                                    act_defn1
                                                                    else
                                                                    (let uu___29
                                                                    =
                                                                    FStarC_Syntax_Subst.close_univ_vars
                                                                    act1.FStarC_Syntax_Syntax.action_univs
                                                                    act_defn1 in
                                                                    ((act1.FStarC_Syntax_Syntax.action_univs),
                                                                    uu___29)) in
                                                                    match uu___28
                                                                    with
                                                                    | 
                                                                    (univs,
                                                                    act_defn2)
                                                                    ->
                                                                    let act_typ4
                                                                    =
                                                                    FStarC_TypeChecker_Normalize.normalize
                                                                    [FStarC_TypeChecker_Env.Beta]
                                                                    env1
                                                                    act_typ3 in
                                                                    let act_typ5
                                                                    =
                                                                    FStarC_Syntax_Subst.close_univ_vars
                                                                    univs
                                                                    act_typ4 in
                                                                    {
                                                                    FStarC_Syntax_Syntax.action_name
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_name);
                                                                    FStarC_Syntax_Syntax.action_unqualified_name
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_unqualified_name);
                                                                    FStarC_Syntax_Syntax.action_univs
                                                                    = univs;
                                                                    FStarC_Syntax_Syntax.action_params
                                                                    =
                                                                    (act1.FStarC_Syntax_Syntax.action_params);
                                                                    FStarC_Syntax_Syntax.action_defn
                                                                    =
                                                                    act_defn2;
                                                                    FStarC_Syntax_Syntax.action_typ
                                                                    =
                                                                    act_typ5
                                                                    })))))))) in
                                           FStarC_List.map check_action
                                             ed2.FStarC_Syntax_Syntax.actions in
                                         ((FStar_Pervasives_Native.Some repr),
                                           (FStar_Pervasives_Native.Some
                                              return_repr),
                                           (FStar_Pervasives_Native.Some
                                              bind_repr), actions))))) in
                               match uu___13 with
                               | (repr, return_repr, bind_repr, actions) ->
                                   let cl ts =
                                     let ts1 =
                                       FStarC_Syntax_Subst.close_tscheme
                                         ed_bs ts in
                                     let ed_univs_closing =
                                       FStarC_Syntax_Subst.univ_var_closing
                                         ed_univs in
                                     let uu___14 =
                                       FStarC_Syntax_Subst.shift_subst
                                         (FStarC_List.length ed_bs)
                                         ed_univs_closing in
                                     FStarC_Syntax_Subst.subst_tscheme
                                       uu___14 ts1 in
                                   let combinators =
                                     {
                                       FStarC_Syntax_Syntax.ret_wp = ret_wp;
                                       FStarC_Syntax_Syntax.bind_wp = bind_wp;
                                       FStarC_Syntax_Syntax.stronger =
                                         stronger;
                                       FStarC_Syntax_Syntax.if_then_else =
                                         if_then_else;
                                       FStarC_Syntax_Syntax.ite_wp = ite_wp;
                                       FStarC_Syntax_Syntax.close_wp =
                                         close_wp;
                                       FStarC_Syntax_Syntax.trivial = trivial;
                                       FStarC_Syntax_Syntax.repr = repr;
                                       FStarC_Syntax_Syntax.return_repr =
                                         return_repr;
                                       FStarC_Syntax_Syntax.bind_repr =
                                         bind_repr
                                     } in
                                   let combinators1 =
                                     FStarC_Syntax_Util.apply_wp_eff_combinators
                                       cl combinators in
                                   let combinators2 =
                                     match ed2.FStarC_Syntax_Syntax.combinators
                                     with
                                     | FStarC_Syntax_Syntax.Primitive_eff
                                         uu___14 ->
                                         FStarC_Syntax_Syntax.Primitive_eff
                                           combinators1
                                     | uu___14 ->
                                         FStarC_Effect.failwith
                                           "Impossible! tc_eff_decl on a layered effect is not expected" in
                                   let ed3 =
                                     let uu___14 =
                                       let uu___15 = cl signature in
                                       FStarC_Syntax_Syntax.WP_eff_sig
                                         uu___15 in
                                     let uu___15 =
                                       FStarC_List.map
                                         (fun a ->
                                            let uu___16 =
                                              let uu___17 =
                                                cl
                                                  ((a.FStarC_Syntax_Syntax.action_univs),
                                                    (a.FStarC_Syntax_Syntax.action_defn)) in
                                              FStar_Pervasives_Native.snd
                                                uu___17 in
                                            let uu___17 =
                                              let uu___18 =
                                                cl
                                                  ((a.FStarC_Syntax_Syntax.action_univs),
                                                    (a.FStarC_Syntax_Syntax.action_typ)) in
                                              FStar_Pervasives_Native.snd
                                                uu___18 in
                                            {
                                              FStarC_Syntax_Syntax.action_name
                                                =
                                                (a.FStarC_Syntax_Syntax.action_name);
                                              FStarC_Syntax_Syntax.action_unqualified_name
                                                =
                                                (a.FStarC_Syntax_Syntax.action_unqualified_name);
                                              FStarC_Syntax_Syntax.action_univs
                                                =
                                                (a.FStarC_Syntax_Syntax.action_univs);
                                              FStarC_Syntax_Syntax.action_params
                                                =
                                                (a.FStarC_Syntax_Syntax.action_params);
                                              FStarC_Syntax_Syntax.action_defn
                                                = uu___16;
                                              FStarC_Syntax_Syntax.action_typ
                                                = uu___17
                                            }) actions in
                                     {
                                       FStarC_Syntax_Syntax.mname =
                                         (ed2.FStarC_Syntax_Syntax.mname);
                                       FStarC_Syntax_Syntax.cattributes =
                                         (ed2.FStarC_Syntax_Syntax.cattributes);
                                       FStarC_Syntax_Syntax.univs =
                                         (ed2.FStarC_Syntax_Syntax.univs);
                                       FStarC_Syntax_Syntax.binders =
                                         (ed2.FStarC_Syntax_Syntax.binders);
                                       FStarC_Syntax_Syntax.signature =
                                         uu___14;
                                       FStarC_Syntax_Syntax.combinators =
                                         combinators2;
                                       FStarC_Syntax_Syntax.actions = uu___15;
                                       FStarC_Syntax_Syntax.eff_attrs =
                                         (ed2.FStarC_Syntax_Syntax.eff_attrs);
                                       FStarC_Syntax_Syntax.extraction_mode =
                                         (ed2.FStarC_Syntax_Syntax.extraction_mode)
                                     } in
                                   ((let uu___15 = FStarC_Effect.op_Bang dbg in
                                     if uu___15
                                     then
                                       let uu___16 =
                                         FStarC_Class_Show.show
                                           FStarC_Syntax_Print.showable_eff_decl
                                           ed3 in
                                       FStarC_Format.print1
                                         "Typechecked effect declaration:\n\t%s\n"
                                         uu___16
                                     else ());
                                    ed3))))))))))))))
let tc_eff_decl (env : FStarC_TypeChecker_Env.env)
  (ed : FStarC_Syntax_Syntax.eff_decl)
  (quals : FStarC_Syntax_Syntax.qualifier Prims.list)
  (attrs : FStarC_Syntax_Syntax.attribute Prims.list) :
  FStarC_Syntax_Syntax.eff_decl=
  if FStarC_Syntax_Util.is_layered ed
  then tc_layered_eff_decl env ed quals attrs
  else tc_non_layered_eff_decl env ed quals attrs
let monad_signature (env : FStarC_TypeChecker_Env.env)
  (m : FStarC_Ident.lident) (s : FStarC_Syntax_Syntax.term) :
  (FStarC_Syntax_Syntax.bv * FStarC_Syntax_Syntax.term'
    FStarC_Syntax_Syntax.syntax)=
  let fail uu___ =
    FStarC_TypeChecker_Err.unexpected_signature_for_monad env
      (FStarC_Ident.range_of_lid m) m s in
  let s1 = FStarC_Syntax_Subst.compress s in
  match s1.FStarC_Syntax_Syntax.n with
  | FStarC_Syntax_Syntax.Tm_arrow
      { FStarC_Syntax_Syntax.bs1 = bs; FStarC_Syntax_Syntax.comp = c;_} ->
      let bs1 = FStarC_Syntax_Subst.open_binders bs in
      (match bs1 with
       | { FStarC_Syntax_Syntax.binder_bv = a;
           FStarC_Syntax_Syntax.binder_qual = uu___;
           FStarC_Syntax_Syntax.binder_positivity = uu___1;
           FStarC_Syntax_Syntax.binder_attrs = uu___2;_}::{
                                                            FStarC_Syntax_Syntax.binder_bv
                                                              = wp;
                                                            FStarC_Syntax_Syntax.binder_qual
                                                              = uu___3;
                                                            FStarC_Syntax_Syntax.binder_positivity
                                                              = uu___4;
                                                            FStarC_Syntax_Syntax.binder_attrs
                                                              = uu___5;_}::[]
           -> (a, (wp.FStarC_Syntax_Syntax.sort))
       | uu___ -> fail ())
  | uu___ -> fail ()
let tc_layered_lift (env0 : FStarC_TypeChecker_Env.env)
  (sub : FStarC_Syntax_Syntax.sub_eff) : FStarC_Syntax_Syntax.sub_eff=
  (let uu___1 = FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
   if uu___1
   then
     let uu___2 =
       FStarC_Class_Show.show FStarC_Syntax_Print.showable_sub_eff sub in
     FStarC_Format.print1 "Typechecking sub_effect: %s\n" uu___2
   else ());
  (let lift_ts = FStarC_Option.must sub.FStarC_Syntax_Syntax.lift in
   let r = (FStar_Pervasives_Native.snd lift_ts).FStarC_Syntax_Syntax.pos in
   let uu___1 = check_and_gen env0 "" "lift" Prims.int_one lift_ts in
   match uu___1 with
   | (us, lift, lift_ty) ->
       ((let uu___3 = FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
         if uu___3
         then
           let uu___4 = FStarC_Syntax_Print.tscheme_to_string (us, lift) in
           let uu___5 = FStarC_Syntax_Print.tscheme_to_string (us, lift_ty) in
           FStarC_Format.print2 "Typechecked lift: %s and lift_ty: %s\n"
             uu___4 uu___5
         else ());
        (let uu___3 = FStarC_Syntax_Subst.open_univ_vars us lift_ty in
         match uu___3 with
         | (us1, lift_ty1) ->
             let env = FStarC_TypeChecker_Env.push_univ_vars env0 us1 in
             let uu___4 =
               validate_indexed_effect_lift_shape env
                 sub.FStarC_Syntax_Syntax.source
                 sub.FStarC_Syntax_Syntax.target (FStarC_List.hd us1)
                 lift_ty1 r in
             (match uu___4 with
              | (k, kind) ->
                  let sub1 =
                    let uu___5 =
                      let uu___6 =
                        let uu___7 =
                          FStarC_Syntax_Subst.close_univ_vars us1 k in
                        (us1, uu___7) in
                      FStar_Pervasives_Native.Some uu___6 in
                    {
                      FStarC_Syntax_Syntax.source =
                        (sub.FStarC_Syntax_Syntax.source);
                      FStarC_Syntax_Syntax.target =
                        (sub.FStarC_Syntax_Syntax.target);
                      FStarC_Syntax_Syntax.lift_wp = uu___5;
                      FStarC_Syntax_Syntax.lift =
                        (FStar_Pervasives_Native.Some (us1, lift));
                      FStarC_Syntax_Syntax.kind =
                        (FStar_Pervasives_Native.Some kind)
                    } in
                  ((let uu___6 = FStarC_Effect.op_Bang dbg_LayeredEffectsTc in
                    if uu___6
                    then
                      let uu___7 =
                        FStarC_Class_Show.show
                          FStarC_Syntax_Print.showable_sub_eff sub1 in
                      FStarC_Format.print1 "Final sub_effect: %s\n" uu___7
                    else ());
                   sub1)))))
let check_lift_for_erasable_effects (env : FStarC_TypeChecker_Env.env)
  (m1 : FStarC_Ident.lident) (m2 : FStarC_Ident.lident)
  (r : FStarC_Range_Type.t) : unit=
  let err reason =
    FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
      FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
      (Obj.magic FStarC_Errors_Msg.is_error_message_string)
      (Obj.magic
         (FStarC_Format.fmt3 "Error defining a lift/subcomp %s ~> %s: %s"
            (FStarC_Ident.string_of_lid m1) (FStarC_Ident.string_of_lid m2)
            reason)) in
  let m11 = FStarC_TypeChecker_Env.norm_eff_name env m1 in
  if FStarC_Ident.lid_equals m11 FStarC_Parser_Const.effect_GHOST_lid
  then err "user-defined lifts from GHOST effect are not allowed"
  else
    (let m1_erasable = FStarC_TypeChecker_Env.is_erasable_effect env m11 in
     let m2_erasable = FStarC_TypeChecker_Env.is_erasable_effect env m2 in
     if
       (m2_erasable && (Prims.op_Negation m1_erasable)) &&
         (Prims.op_Negation
            (FStarC_Ident.lid_equals m11 FStarC_Parser_Const.effect_PURE_lid))
     then
       err
         "cannot lift a non-erasable effect to an erasable effect unless the non-erasable effect is PURE"
     else ())
let tc_lift (env : FStarC_TypeChecker_Env.env)
  (sub : FStarC_Syntax_Syntax.sub_eff) (r : FStarC_Range_Type.t) :
  FStarC_Syntax_Syntax.sub_eff=
  if
    FStarC_Ident.lid_equals sub.FStarC_Syntax_Syntax.source
      sub.FStarC_Syntax_Syntax.target
  then
    (let uu___1 =
       let uu___2 =
         FStarC_Class_Show.show FStarC_Ident.showable_lident
           sub.FStarC_Syntax_Syntax.source in
       FStarC_Format.fmt1
         "Cannot define a lift with same source and target (%s)" uu___2 in
     FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
       FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
       (Obj.magic FStarC_Errors_Msg.is_error_message_string)
       (Obj.magic uu___1))
  else ();
  (let check_and_gen1 env1 t k =
     let uu___1 = FStarC_TypeChecker_TcTerm.tc_check_trivial_guard env1 t k in
     FStarC_TypeChecker_Generalize.generalize_universes env1 uu___1 in
   check_lift_for_erasable_effects env sub.FStarC_Syntax_Syntax.source
     sub.FStarC_Syntax_Syntax.target r;
   (let ed_src =
      FStarC_TypeChecker_Env.get_effect_decl env
        sub.FStarC_Syntax_Syntax.source in
    let ed_tgt =
      FStarC_TypeChecker_Env.get_effect_decl env
        sub.FStarC_Syntax_Syntax.target in
    if
      (FStarC_Syntax_Util.is_layered ed_src) ||
        (FStarC_Syntax_Util.is_layered ed_tgt)
    then tc_layered_lift (FStarC_TypeChecker_Env.set_range env r) sub
    else
      (let uu___2 =
         let uu___3 =
           FStarC_TypeChecker_Env.lookup_effect_lid env
             sub.FStarC_Syntax_Syntax.source in
         monad_signature env sub.FStarC_Syntax_Syntax.source uu___3 in
       match uu___2 with
       | (a, wp_a_src) ->
           let uu___3 =
             let uu___4 =
               FStarC_TypeChecker_Env.lookup_effect_lid env
                 sub.FStarC_Syntax_Syntax.target in
             monad_signature env sub.FStarC_Syntax_Syntax.target uu___4 in
           (match uu___3 with
            | (b, wp_b_tgt) ->
                let wp_a_tgt =
                  let uu___4 =
                    let uu___5 =
                      let uu___6 =
                        let uu___7 = FStarC_Syntax_Syntax.bv_to_name a in
                        (b, uu___7) in
                      FStarC_Syntax_Syntax.NT uu___6 in
                    [uu___5] in
                  FStarC_Syntax_Subst.subst uu___4 wp_b_tgt in
                let expected_k =
                  let uu___4 =
                    let uu___5 =
                      let uu___6 = FStarC_Syntax_Syntax.null_binder wp_a_src in
                      [uu___6] in
                    (FStarC_Syntax_Syntax.mk_binder a) :: uu___5 in
                  let uu___5 = FStarC_Syntax_Syntax.mk_Total wp_a_tgt in
                  FStarC_Syntax_Util.arrow uu___4 uu___5 in
                let repr_type eff_name a1 wp =
                  (let uu___5 =
                     let uu___6 =
                       FStarC_TypeChecker_Env.is_reifiable_effect env
                         eff_name in
                     Prims.op_Negation uu___6 in
                   if uu___5
                   then
                     FStarC_Errors.raise_error
                       FStarC_TypeChecker_Env.hasRange_env env
                       FStarC_Errors_Codes.Fatal_EffectCannotBeReified ()
                       (Obj.magic FStarC_Errors_Msg.is_error_message_string)
                       (Obj.magic
                          (FStarC_Format.fmt1 "Effect %s cannot be reified"
                             (FStarC_Ident.string_of_lid eff_name)))
                   else ());
                  (let uu___5 =
                     FStarC_TypeChecker_Env.effect_decl_opt env eff_name in
                   match uu___5 with
                   | FStar_Pervasives_Native.None ->
                       FStarC_Effect.failwith
                         "internal error: reifiable effect has no decl?"
                   | FStar_Pervasives_Native.Some (ed, qualifiers) ->
                       let repr =
                         let uu___6 =
                           FStarC_Option.must
                             (FStarC_Syntax_Util.get_eff_repr ed) in
                         FStarC_TypeChecker_Env.inst_effect_fun_with
                           [FStarC_Syntax_Syntax.U_unknown] env ed uu___6 in
                       FStarC_Syntax_Syntax.mk
                         (FStarC_Syntax_Syntax.Tm_app
                            {
                              FStarC_Syntax_Syntax.hd = repr;
                              FStarC_Syntax_Syntax.args =
                                [FStarC_Syntax_Syntax.as_arg a1;
                                FStarC_Syntax_Syntax.as_arg wp]
                            }) (FStarC_TypeChecker_Env.get_range env)) in
                let uu___4 =
                  match ((sub.FStarC_Syntax_Syntax.lift),
                          (sub.FStarC_Syntax_Syntax.lift_wp))
                  with
                  | (FStar_Pervasives_Native.None,
                     FStar_Pervasives_Native.None) ->
                      FStarC_Effect.failwith "Impossible (parser)"
                  | (lift, FStar_Pervasives_Native.Some (uvs, lift_wp)) ->
                      let uu___5 =
                        if Prims.uu___is_Cons uvs
                        then
                          let uu___6 =
                            FStarC_Syntax_Subst.univ_var_opening uvs in
                          match uu___6 with
                          | (usubst, uvs1) ->
                              let uu___7 =
                                FStarC_TypeChecker_Env.push_univ_vars env
                                  uvs1 in
                              let uu___8 =
                                FStarC_Syntax_Subst.subst usubst lift_wp in
                              (uu___7, uu___8)
                        else (env, lift_wp) in
                      (match uu___5 with
                       | (env1, lift_wp1) ->
                           let lift_wp2 =
                             if Prims.uu___is_Nil uvs
                             then check_and_gen1 env1 lift_wp1 expected_k
                             else
                               (let lift_wp3 =
                                  FStarC_TypeChecker_TcTerm.tc_check_trivial_guard
                                    env1 lift_wp1 expected_k in
                                let uu___6 =
                                  FStarC_Syntax_Subst.close_univ_vars uvs
                                    lift_wp3 in
                                (uvs, uu___6)) in
                           (lift, lift_wp2))
                  | (FStar_Pervasives_Native.Some uu___5,
                     FStar_Pervasives_Native.None) ->
                      FStarC_Effect.failwith
                        "Sub-effect for free (DM4F) has been removed" in
                (match uu___4 with
                 | (lift, lift_wp) ->
                     let env1 =
                       {
                         FStarC_TypeChecker_Env.solver =
                           (env.FStarC_TypeChecker_Env.solver);
                         FStarC_TypeChecker_Env.range =
                           (env.FStarC_TypeChecker_Env.range);
                         FStarC_TypeChecker_Env.curmodule =
                           (env.FStarC_TypeChecker_Env.curmodule);
                         FStarC_TypeChecker_Env.gamma =
                           (env.FStarC_TypeChecker_Env.gamma);
                         FStarC_TypeChecker_Env.gamma_sig =
                           (env.FStarC_TypeChecker_Env.gamma_sig);
                         FStarC_TypeChecker_Env.gamma_cache =
                           (env.FStarC_TypeChecker_Env.gamma_cache);
                         FStarC_TypeChecker_Env.modules =
                           (env.FStarC_TypeChecker_Env.modules);
                         FStarC_TypeChecker_Env.expected_typ =
                           (env.FStarC_TypeChecker_Env.expected_typ);
                         FStarC_TypeChecker_Env.sigtab =
                           (env.FStarC_TypeChecker_Env.sigtab);
                         FStarC_TypeChecker_Env.attrtab =
                           (env.FStarC_TypeChecker_Env.attrtab);
                         FStarC_TypeChecker_Env.instantiate_imp =
                           (env.FStarC_TypeChecker_Env.instantiate_imp);
                         FStarC_TypeChecker_Env.effects =
                           (env.FStarC_TypeChecker_Env.effects);
                         FStarC_TypeChecker_Env.generalize =
                           (env.FStarC_TypeChecker_Env.generalize);
                         FStarC_TypeChecker_Env.letrecs =
                           (env.FStarC_TypeChecker_Env.letrecs);
                         FStarC_TypeChecker_Env.top_level =
                           (env.FStarC_TypeChecker_Env.top_level);
                         FStarC_TypeChecker_Env.check_uvars =
                           (env.FStarC_TypeChecker_Env.check_uvars);
                         FStarC_TypeChecker_Env.use_eq_strict =
                           (env.FStarC_TypeChecker_Env.use_eq_strict);
                         FStarC_TypeChecker_Env.is_iface =
                           (env.FStarC_TypeChecker_Env.is_iface);
                         FStarC_TypeChecker_Env.admit = true;
                         FStarC_TypeChecker_Env.phase1 =
                           (env.FStarC_TypeChecker_Env.phase1);
                         FStarC_TypeChecker_Env.failhard =
                           (env.FStarC_TypeChecker_Env.failhard);
                         FStarC_TypeChecker_Env.flychecking =
                           (env.FStarC_TypeChecker_Env.flychecking);
                         FStarC_TypeChecker_Env.uvar_subtyping =
                           (env.FStarC_TypeChecker_Env.uvar_subtyping);
                         FStarC_TypeChecker_Env.intactics =
                           (env.FStarC_TypeChecker_Env.intactics);
                         FStarC_TypeChecker_Env.nocoerce =
                           (env.FStarC_TypeChecker_Env.nocoerce);
                         FStarC_TypeChecker_Env.tc_term =
                           (env.FStarC_TypeChecker_Env.tc_term);
                         FStarC_TypeChecker_Env.typeof_tot_or_gtot_term =
                           (env.FStarC_TypeChecker_Env.typeof_tot_or_gtot_term);
                         FStarC_TypeChecker_Env.universe_of =
                           (env.FStarC_TypeChecker_Env.universe_of);
                         FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term
                           =
                           (env.FStarC_TypeChecker_Env.typeof_well_typed_tot_or_gtot_term);
                         FStarC_TypeChecker_Env.teq_nosmt_force =
                           (env.FStarC_TypeChecker_Env.teq_nosmt_force);
                         FStarC_TypeChecker_Env.subtype_nosmt_force =
                           (env.FStarC_TypeChecker_Env.subtype_nosmt_force);
                         FStarC_TypeChecker_Env.qtbl_name_and_index =
                           (env.FStarC_TypeChecker_Env.qtbl_name_and_index);
                         FStarC_TypeChecker_Env.normalized_eff_names =
                           (env.FStarC_TypeChecker_Env.normalized_eff_names);
                         FStarC_TypeChecker_Env.fv_delta_depths =
                           (env.FStarC_TypeChecker_Env.fv_delta_depths);
                         FStarC_TypeChecker_Env.proof_ns =
                           (env.FStarC_TypeChecker_Env.proof_ns);
                         FStarC_TypeChecker_Env.synth_hook =
                           (env.FStarC_TypeChecker_Env.synth_hook);
                         FStarC_TypeChecker_Env.try_solve_implicits_hook =
                           (env.FStarC_TypeChecker_Env.try_solve_implicits_hook);
                         FStarC_TypeChecker_Env.splice =
                           (env.FStarC_TypeChecker_Env.splice);
                         FStarC_TypeChecker_Env.mpreprocess =
                           (env.FStarC_TypeChecker_Env.mpreprocess);
                         FStarC_TypeChecker_Env.postprocess =
                           (env.FStarC_TypeChecker_Env.postprocess);
                         FStarC_TypeChecker_Env.identifier_info =
                           (env.FStarC_TypeChecker_Env.identifier_info);
                         FStarC_TypeChecker_Env.tc_hooks =
                           (env.FStarC_TypeChecker_Env.tc_hooks);
                         FStarC_TypeChecker_Env.dsenv =
                           (env.FStarC_TypeChecker_Env.dsenv);
                         FStarC_TypeChecker_Env.nbe =
                           (env.FStarC_TypeChecker_Env.nbe);
                         FStarC_TypeChecker_Env.strict_args_tab =
                           (env.FStarC_TypeChecker_Env.strict_args_tab);
                         FStarC_TypeChecker_Env.erasable_types_tab =
                           (env.FStarC_TypeChecker_Env.erasable_types_tab);
                         FStarC_TypeChecker_Env.enable_defer_to_tac =
                           (env.FStarC_TypeChecker_Env.enable_defer_to_tac);
                         FStarC_TypeChecker_Env.unif_allow_ref_guards =
                           (env.FStarC_TypeChecker_Env.unif_allow_ref_guards);
                         FStarC_TypeChecker_Env.erase_erasable_args =
                           (env.FStarC_TypeChecker_Env.erase_erasable_args);
                         FStarC_TypeChecker_Env.core_check =
                           (env.FStarC_TypeChecker_Env.core_check);
                         FStarC_TypeChecker_Env.missing_decl =
                           (env.FStarC_TypeChecker_Env.missing_decl)
                       } in
                     let lift1 =
                       match lift with
                       | FStar_Pervasives_Native.None ->
                           FStar_Pervasives_Native.None
                       | FStar_Pervasives_Native.Some (uvs, lift2) ->
                           let uu___5 =
                             let uu___6 =
                               FStarC_Syntax_Subst.univ_var_opening uvs in
                             match uu___6 with
                             | (usubst, uvs1) ->
                                 let uu___7 =
                                   FStarC_TypeChecker_Env.push_univ_vars env1
                                     uvs1 in
                                 let uu___8 =
                                   FStarC_Syntax_Subst.subst usubst lift2 in
                                 (uu___7, uu___8) in
                           (match uu___5 with
                            | (env2, lift3) ->
                                let uu___6 =
                                  let uu___7 =
                                    FStarC_TypeChecker_Env.lookup_effect_lid
                                      env2 sub.FStarC_Syntax_Syntax.source in
                                  monad_signature env2
                                    sub.FStarC_Syntax_Syntax.source uu___7 in
                                (match uu___6 with
                                 | (a1, wp_a_src1) ->
                                     let wp_a =
                                       FStarC_Syntax_Syntax.new_bv
                                         FStar_Pervasives_Native.None
                                         wp_a_src1 in
                                     let a_typ =
                                       FStarC_Syntax_Syntax.bv_to_name a1 in
                                     let wp_a_typ =
                                       FStarC_Syntax_Syntax.bv_to_name wp_a in
                                     let repr_f =
                                       repr_type
                                         sub.FStarC_Syntax_Syntax.source
                                         a_typ wp_a_typ in
                                     let repr_result =
                                       let lift_wp1 =
                                         FStarC_TypeChecker_Normalize.normalize
                                           [FStarC_TypeChecker_Env.EraseUniverses;
                                           FStarC_TypeChecker_Env.AllowUnboundUniverses]
                                           env2
                                           (FStar_Pervasives_Native.snd
                                              lift_wp) in
                                       let lift_wp_a =
                                         FStarC_Syntax_Syntax.mk
                                           (FStarC_Syntax_Syntax.Tm_app
                                              {
                                                FStarC_Syntax_Syntax.hd =
                                                  lift_wp1;
                                                FStarC_Syntax_Syntax.args =
                                                  [FStarC_Syntax_Syntax.as_arg
                                                     a_typ;
                                                  FStarC_Syntax_Syntax.as_arg
                                                    wp_a_typ]
                                              })
                                           (FStarC_TypeChecker_Env.get_range
                                              env2) in
                                       repr_type
                                         sub.FStarC_Syntax_Syntax.target
                                         a_typ lift_wp_a in
                                     let expected_k1 =
                                       let uu___7 =
                                         let uu___8 =
                                           let uu___9 =
                                             let uu___10 =
                                               FStarC_Syntax_Syntax.null_binder
                                                 repr_f in
                                             [uu___10] in
                                           (FStarC_Syntax_Syntax.mk_binder
                                              wp_a)
                                             :: uu___9 in
                                         (FStarC_Syntax_Syntax.mk_binder a1)
                                           :: uu___8 in
                                       let uu___8 =
                                         FStarC_Syntax_Syntax.mk_Total
                                           repr_result in
                                       FStarC_Syntax_Util.arrow uu___7 uu___8 in
                                     let uu___7 =
                                       FStarC_TypeChecker_TcTerm.tc_tot_or_gtot_term
                                         env2 expected_k1 in
                                     (match uu___7 with
                                      | (expected_k2, uu___8, uu___9) ->
                                          let lift4 =
                                            if Prims.uu___is_Nil uvs
                                            then
                                              check_and_gen1 env2 lift3
                                                expected_k2
                                            else
                                              (let lift5 =
                                                 FStarC_TypeChecker_TcTerm.tc_check_trivial_guard
                                                   env2 lift3 expected_k2 in
                                               let uu___10 =
                                                 FStarC_Syntax_Subst.close_univ_vars
                                                   uvs lift5 in
                                               (uvs, uu___10)) in
                                          FStar_Pervasives_Native.Some lift4))) in
                     (if
                        (FStarC_List.length
                           (FStar_Pervasives_Native.fst lift_wp))
                          <> Prims.int_one
                      then
                        (let uu___6 =
                           let uu___7 =
                             FStarC_Class_Show.show
                               FStarC_Ident.showable_lident
                               sub.FStarC_Syntax_Syntax.source in
                           let uu___8 =
                             FStarC_Class_Show.show
                               FStarC_Ident.showable_lident
                               sub.FStarC_Syntax_Syntax.target in
                           let uu___9 =
                             FStarC_Class_Show.show
                               FStarC_Class_Show.showable_nat
                               (FStarC_List.length
                                  (FStar_Pervasives_Native.fst lift_wp)) in
                           FStarC_Format.fmt3
                             "Sub effect wp must be polymorphic in exactly 1 universe; %s ~> %s has %s universes"
                             uu___7 uu___8 uu___9 in
                         FStarC_Errors.raise_error
                           FStarC_Class_HasRange.hasRange_range r
                           FStarC_Errors_Codes.Fatal_TooManyUniverse ()
                           (Obj.magic
                              FStarC_Errors_Msg.is_error_message_string)
                           (Obj.magic uu___6))
                      else ();
                      (let uu___7 =
                         if FStar_Pervasives_Native.uu___is_Some lift1
                         then
                           let uu___8 =
                             let uu___9 =
                               let uu___10 = FStarC_Option.must lift1 in
                               FStar_Pervasives_Native.fst uu___10 in
                             FStarC_List.length uu___9 in
                           uu___8 <> Prims.int_one
                         else false in
                       if uu___7
                       then
                         let uu___8 =
                           let uu___9 =
                             FStarC_Class_Show.show
                               FStarC_Ident.showable_lident
                               sub.FStarC_Syntax_Syntax.source in
                           let uu___10 =
                             FStarC_Class_Show.show
                               FStarC_Ident.showable_lident
                               sub.FStarC_Syntax_Syntax.target in
                           let uu___11 =
                             let uu___12 =
                               let uu___13 =
                                 let uu___14 = FStarC_Option.must lift1 in
                                 FStar_Pervasives_Native.fst uu___14 in
                               FStarC_List.length uu___13 in
                             FStarC_Class_Show.show
                               FStarC_Class_Show.showable_nat uu___12 in
                           FStarC_Format.fmt3
                             "Sub effect lift must be polymorphic in exactly 1 universe; %s ~> %s has %s universes"
                             uu___9 uu___10 uu___11 in
                         FStarC_Errors.raise_error
                           FStarC_Class_HasRange.hasRange_range r
                           FStarC_Errors_Codes.Fatal_TooManyUniverse ()
                           (Obj.magic
                              FStarC_Errors_Msg.is_error_message_string)
                           (Obj.magic uu___8)
                       else ());
                      {
                        FStarC_Syntax_Syntax.source =
                          (sub.FStarC_Syntax_Syntax.source);
                        FStarC_Syntax_Syntax.target =
                          (sub.FStarC_Syntax_Syntax.target);
                        FStarC_Syntax_Syntax.lift_wp =
                          (FStar_Pervasives_Native.Some lift_wp);
                        FStarC_Syntax_Syntax.lift = lift1;
                        FStarC_Syntax_Syntax.kind =
                          (sub.FStarC_Syntax_Syntax.kind)
                      }))))))
let tc_effect_abbrev (env : FStarC_TypeChecker_Env.env)
  (lid_uvs_tps_c :
    (FStarC_Ident.lident * FStarC_Syntax_Syntax.univ_names *
      FStarC_Syntax_Syntax.binders * FStarC_Syntax_Syntax.comp))
  (r : FStarC_Range_Type.t) :
  (FStarC_Ident.lident * FStarC_Syntax_Syntax.univ_names *
    FStarC_Syntax_Syntax.binders * FStarC_Syntax_Syntax.comp)=
  let uu___ = lid_uvs_tps_c in
  match uu___ with
  | (lid, uvs, tps, c) ->
      let env0 = env in
      let uu___1 =
        if Prims.uu___is_Nil uvs
        then (env, uvs, tps, c)
        else
          (let uu___2 = FStarC_Syntax_Subst.univ_var_opening uvs in
           match uu___2 with
           | (usubst, uvs1) ->
               let tps1 = FStarC_Syntax_Subst.subst_binders usubst tps in
               let c1 =
                 let uu___3 =
                   FStarC_Syntax_Subst.shift_subst (FStarC_List.length tps1)
                     usubst in
                 FStarC_Syntax_Subst.subst_comp uu___3 c in
               let uu___3 = FStarC_TypeChecker_Env.push_univ_vars env uvs1 in
               (uu___3, uvs1, tps1, c1)) in
      (match uu___1 with
       | (env1, uvs1, tps1, c1) ->
           let env2 = FStarC_TypeChecker_Env.set_range env1 r in
           let uu___2 = FStarC_Syntax_Subst.open_comp tps1 c1 in
           (match uu___2 with
            | (tps2, c2) ->
                let uu___3 = FStarC_TypeChecker_TcTerm.tc_tparams env2 tps2 in
                (match uu___3 with
                 | (tps3, env3, us) ->
                     let uu___4 = FStarC_TypeChecker_TcTerm.tc_comp env3 c2 in
                     (match uu___4 with
                      | (c3, u, g) ->
                          let is_default_effect =
                            let uu___5 =
                              FStarC_TypeChecker_Env.get_default_effect env3
                                (FStarC_Syntax_Util.comp_effect_name c3) in
                            match uu___5 with
                            | FStar_Pervasives_Native.None -> false
                            | FStar_Pervasives_Native.Some l ->
                                FStarC_Ident.lid_equals l lid in
                          (FStarC_TypeChecker_Rel.force_trivial_guard env3 g;
                           (let expected_result_typ =
                              match tps3 with
                              | { FStarC_Syntax_Syntax.binder_bv = x;
                                  FStarC_Syntax_Syntax.binder_qual = uu___7;
                                  FStarC_Syntax_Syntax.binder_positivity =
                                    uu___8;
                                  FStarC_Syntax_Syntax.binder_attrs = uu___9;_}::tl
                                  ->
                                  (if
                                     is_default_effect &&
                                       (Prims.op_Negation (tl = []))
                                   then
                                     FStarC_Errors.raise_error
                                       FStarC_Class_HasRange.hasRange_range r
                                       FStarC_Errors_Codes.Fatal_UnexpectedEffect
                                       ()
                                       (Obj.magic
                                          FStarC_Errors_Msg.is_error_message_string)
                                       (Obj.magic
                                          (FStarC_Format.fmt2
                                             "Effect %s is marked as a default effect for %s, but it has more than one arguments"
                                             (FStarC_Ident.string_of_lid lid)
                                             (FStarC_Ident.string_of_lid
                                                (FStarC_Syntax_Util.comp_effect_name
                                                   c3))))
                                   else ();
                                   FStarC_Syntax_Syntax.bv_to_name x)
                              | uu___7 ->
                                  FStarC_Errors.raise_error
                                    FStarC_Class_HasRange.hasRange_range r
                                    FStarC_Errors_Codes.Fatal_NotEnoughArgumentsForEffect
                                    ()
                                    (Obj.magic
                                       FStarC_Errors_Msg.is_error_message_string)
                                    (Obj.magic
                                       "Effect abbreviations must bind at least the result type") in
                            let def_result_typ =
                              FStarC_Syntax_Util.comp_result c3 in
                            let uu___7 =
                              let uu___8 =
                                FStarC_TypeChecker_Rel.teq_nosmt_force env3
                                  expected_result_typ def_result_typ in
                              Prims.op_Negation uu___8 in
                            if uu___7
                            then
                              let uu___8 =
                                let uu___9 =
                                  FStarC_Class_Show.show
                                    FStarC_Syntax_Print.showable_term
                                    expected_result_typ in
                                let uu___10 =
                                  FStarC_Class_Show.show
                                    FStarC_Syntax_Print.showable_term
                                    def_result_typ in
                                FStarC_Format.fmt2
                                  "Result type of effect abbreviation \226\128\152%s\226\128\153 does not match the result type of its definition \226\128\152%s\226\128\153"
                                  uu___9 uu___10 in
                              FStarC_Errors.raise_error
                                FStarC_Class_HasRange.hasRange_range r
                                FStarC_Errors_Codes.Fatal_EffectAbbreviationResultTypeMismatch
                                ()
                                (Obj.magic
                                   FStarC_Errors_Msg.is_error_message_string)
                                (Obj.magic uu___8)
                            else ());
                           (let tps4 = FStarC_Syntax_Subst.close_binders tps3 in
                            let c4 = FStarC_Syntax_Subst.close_comp tps4 c3 in
                            let uu___7 =
                              let uu___8 =
                                FStarC_Syntax_Syntax.mk
                                  (FStarC_Syntax_Syntax.Tm_arrow
                                     {
                                       FStarC_Syntax_Syntax.bs1 = tps4;
                                       FStarC_Syntax_Syntax.comp = c4
                                     }) r in
                              FStarC_TypeChecker_Generalize.generalize_universes
                                env0 uu___8 in
                            match uu___7 with
                            | (uvs2, t) ->
                                let uu___8 =
                                  let uu___9 =
                                    let uu___10 =
                                      let uu___11 =
                                        FStarC_Syntax_Subst.compress t in
                                      uu___11.FStarC_Syntax_Syntax.n in
                                    (tps4, uu___10) in
                                  match uu___9 with
                                  | ([], FStarC_Syntax_Syntax.Tm_arrow
                                     { FStarC_Syntax_Syntax.bs1 = uu___10;
                                       FStarC_Syntax_Syntax.comp = c5;_})
                                      -> ([], c5)
                                  | (uu___10, FStarC_Syntax_Syntax.Tm_arrow
                                     { FStarC_Syntax_Syntax.bs1 = tps5;
                                       FStarC_Syntax_Syntax.comp = c5;_})
                                      -> (tps5, c5)
                                  | uu___10 ->
                                      FStarC_Effect.failwith
                                        "Impossible (t is an arrow)" in
                                (match uu___8 with
                                 | (tps5, c5) ->
                                     (if
                                        (FStarC_List.length uvs2) <>
                                          Prims.int_one
                                      then
                                        (let uu___10 =
                                           FStarC_Syntax_Subst.open_univ_vars
                                             uvs2 t in
                                         match uu___10 with
                                         | (uu___11, t1) ->
                                             let uu___12 =
                                               let uu___13 =
                                                 FStarC_Class_Show.show
                                                   FStarC_Ident.showable_lident
                                                   lid in
                                               let uu___14 =
                                                 FStarC_Class_Show.show
                                                   FStarC_Class_Show.showable_nat
                                                   (FStarC_List.length uvs2) in
                                               let uu___15 =
                                                 FStarC_Class_Show.show
                                                   FStarC_Syntax_Print.showable_term
                                                   t1 in
                                               FStarC_Format.fmt3
                                                 "Effect abbreviations must be polymorphic in exactly 1 universe; %s has %s universes (%s)"
                                                 uu___13 uu___14 uu___15 in
                                             FStarC_Errors.raise_error
                                               FStarC_Class_HasRange.hasRange_range
                                               r
                                               FStarC_Errors_Codes.Fatal_TooManyUniverse
                                               ()
                                               (Obj.magic
                                                  FStarC_Errors_Msg.is_error_message_string)
                                               (Obj.magic uu___12))
                                      else ();
                                      (lid, uvs2, tps5, c5)))))))))
let check_polymonadic_bind_for_erasable_effects
  (env : FStarC_TypeChecker_Env.env) (m : FStarC_Ident.lident)
  (n : FStarC_Ident.lident) (p : FStarC_Ident.lident)
  (r : FStarC_Range_Type.t) : unit=
  let err reason =
    let uu___ =
      let uu___1 = FStarC_Class_Show.show FStarC_Ident.showable_lident m in
      let uu___2 = FStarC_Class_Show.show FStarC_Ident.showable_lident n in
      let uu___3 = FStarC_Class_Show.show FStarC_Ident.showable_lident p in
      FStarC_Format.fmt4
        "Error definition polymonadic bind (%s, %s) |> %s: %s" uu___1 uu___2
        uu___3 reason in
    FStarC_Errors.raise_error FStarC_Class_HasRange.hasRange_range r
      FStarC_Errors_Codes.Fatal_UnexpectedEffect ()
      (Obj.magic FStarC_Errors_Msg.is_error_message_string) (Obj.magic uu___) in
  let m1 = FStarC_TypeChecker_Env.norm_eff_name env m in
  let n1 = FStarC_TypeChecker_Env.norm_eff_name env n in
  if
    (FStarC_Ident.lid_equals m1 FStarC_Parser_Const.effect_GHOST_lid) ||
      (FStarC_Ident.lid_equals n1 FStarC_Parser_Const.effect_GHOST_lid)
  then
    err
      "GHOST computations are not allowed to be composed using user-defined polymonadic binds"
  else
    (let m_erasable = FStarC_TypeChecker_Env.is_erasable_effect env m1 in
     let n_erasable = FStarC_TypeChecker_Env.is_erasable_effect env n1 in
     let p_erasable = FStarC_TypeChecker_Env.is_erasable_effect env p in
     if p_erasable
     then
       (if
          (Prims.op_Negation m_erasable) &&
            (Prims.op_Negation
               (FStarC_Ident.lid_equals m1
                  FStarC_Parser_Const.effect_PURE_lid))
        then
          err
            (FStarC_Format.fmt1
               "target effect is erasable but %s is neither erasable nor PURE"
               (FStarC_Ident.string_of_lid m1))
        else
          if
            (Prims.op_Negation n_erasable) &&
              (Prims.op_Negation
                 (FStarC_Ident.lid_equals n1
                    FStarC_Parser_Const.effect_PURE_lid))
          then
            err
              (FStarC_Format.fmt1
                 "target effect is erasable but %s is neither erasable nor PURE"
                 (FStarC_Ident.string_of_lid n1))
          else ())
     else ())
let tc_polymonadic_bind (env : FStarC_TypeChecker_Env.env)
  (m : FStarC_Ident.lident) (n : FStarC_Ident.lident)
  (p : FStarC_Ident.lident) (ts : FStarC_Syntax_Syntax.tscheme) :
  (FStarC_Syntax_Syntax.tscheme * FStarC_Syntax_Syntax.tscheme *
    FStarC_Syntax_Syntax.indexed_effect_combinator_kind)=
  let eff_name =
    FStarC_Format.fmt3 "(%s, %s) |> %s)"
      (FStarC_Ident.string_of_id (FStarC_Ident.ident_of_lid m))
      (FStarC_Ident.string_of_id (FStarC_Ident.ident_of_lid n))
      (FStarC_Ident.string_of_id (FStarC_Ident.ident_of_lid p)) in
  let r = (FStar_Pervasives_Native.snd ts).FStarC_Syntax_Syntax.pos in
  check_polymonadic_bind_for_erasable_effects env m n p r;
  (let uu___1 =
     check_and_gen env eff_name "polymonadic_bind" (Prims.of_int 2) ts in
   match uu___1 with
   | (us, t, ty) ->
       let uu___2 = FStarC_Syntax_Subst.open_univ_vars us ty in
       (match uu___2 with
        | (us1, ty1) ->
            let env1 = FStarC_TypeChecker_Env.push_univ_vars env us1 in
            let uu___3 =
              let uu___4 = FStarC_TypeChecker_Env.get_effect_decl env1 m in
              let uu___5 = FStarC_TypeChecker_Env.get_effect_decl env1 n in
              let uu___6 = FStarC_TypeChecker_Env.get_effect_decl env1 p in
              (uu___4, uu___5, uu___6) in
            (match uu___3 with
             | (m_ed, n_ed, p_ed) ->
                 let uu___4 =
                   validate_indexed_effect_bind_shape env1 m n p
                     (FStarC_Syntax_Util.effect_sig_ts
                        m_ed.FStarC_Syntax_Syntax.signature)
                     (FStarC_Syntax_Util.effect_sig_ts
                        n_ed.FStarC_Syntax_Syntax.signature)
                     (FStarC_Syntax_Util.effect_sig_ts
                        p_ed.FStarC_Syntax_Syntax.signature)
                     (FStarC_Syntax_Util.get_eff_repr m_ed)
                     (FStarC_Syntax_Util.get_eff_repr n_ed)
                     (FStarC_Syntax_Util.get_eff_repr p_ed) us1 ty1
                     (FStarC_TypeChecker_Env.get_range env1) Prims.int_zero
                     false in
                 (match uu___4 with
                  | (k, kind) ->
                      ((let uu___6 = FStarC_Debug.extreme () in
                        if uu___6
                        then
                          let uu___7 =
                            FStarC_Syntax_Print.tscheme_to_string (us1, t) in
                          let uu___8 =
                            FStarC_Syntax_Print.tscheme_to_string (us1, k) in
                          FStarC_Format.print3
                            "Polymonadic bind %s after typechecking (%s::%s)\n"
                            eff_name uu___7 uu___8
                        else ());
                       FStarC_Errors.log_issue
                         FStarC_Class_HasRange.hasRange_range r
                         FStarC_Errors_Codes.Warning_BleedingEdge_Feature ()
                         (Obj.magic
                            FStarC_Errors_Msg.is_error_message_list_doc)
                         (Obj.magic
                            [FStarC_Errors_Msg.text
                               (FStarC_Format.fmt1
                                  "Polymonadic binds (%s in this case) is an experimental feature;it is subject to some redesign in the future. Please keep us informed (on github etc.) about how you are using it"
                                  eff_name)]);
                       (let uu___7 =
                          let uu___8 =
                            FStarC_Syntax_Subst.close_univ_vars us1 k in
                          (us1, uu___8) in
                        ((us1, t), uu___7, kind)))))))
let tc_polymonadic_subcomp (env0 : FStarC_TypeChecker_Env.env)
  (m : FStarC_Ident.lident) (n : FStarC_Ident.lident)
  (ts : FStarC_Syntax_Syntax.tscheme) :
  (FStarC_Syntax_Syntax.tscheme * FStarC_Syntax_Syntax.tscheme *
    FStarC_Syntax_Syntax.indexed_effect_combinator_kind)=
  let r = (FStar_Pervasives_Native.snd ts).FStarC_Syntax_Syntax.pos in
  check_lift_for_erasable_effects env0 m n r;
  (let combinator_name =
     Prims.strcat (FStarC_Ident.string_of_id (FStarC_Ident.ident_of_lid m))
       (Prims.strcat " <: "
          (FStarC_Ident.string_of_id (FStarC_Ident.ident_of_lid n))) in
   let uu___1 =
     check_and_gen env0 combinator_name "polymonadic_subcomp" Prims.int_one
       ts in
   match uu___1 with
   | (us, t, ty) ->
       let uu___2 = FStarC_Syntax_Subst.open_univ_vars us ty in
       (match uu___2 with
        | (us1, ty1) ->
            let env = FStarC_TypeChecker_Env.push_univ_vars env0 us1 in
            let uu___3 =
              let uu___4 = FStarC_TypeChecker_Env.get_effect_decl env m in
              let uu___5 = FStarC_TypeChecker_Env.get_effect_decl env n in
              (uu___4, uu___5) in
            (match uu___3 with
             | (m_ed, n_ed) ->
                 let uu___4 =
                   validate_indexed_effect_subcomp_shape env m n
                     (FStarC_Syntax_Util.effect_sig_ts
                        m_ed.FStarC_Syntax_Syntax.signature)
                     (FStarC_Syntax_Util.effect_sig_ts
                        n_ed.FStarC_Syntax_Syntax.signature)
                     (FStarC_Syntax_Util.get_eff_repr m_ed)
                     (FStarC_Syntax_Util.get_eff_repr n_ed)
                     (FStarC_List.hd us1) ty1 Prims.int_zero
                     (FStarC_TypeChecker_Env.get_range env) in
                 (match uu___4 with
                  | (k, kind) ->
                      ((let uu___6 = FStarC_Debug.extreme () in
                        if uu___6
                        then
                          let uu___7 =
                            FStarC_Syntax_Print.tscheme_to_string (us1, t) in
                          let uu___8 =
                            FStarC_Syntax_Print.tscheme_to_string (us1, k) in
                          FStarC_Format.print3
                            "Polymonadic subcomp %s after typechecking (%s::%s)\n"
                            combinator_name uu___7 uu___8
                        else ());
                       FStarC_Errors.log_issue
                         FStarC_Class_HasRange.hasRange_range r
                         FStarC_Errors_Codes.Warning_BleedingEdge_Feature ()
                         (Obj.magic
                            FStarC_Errors_Msg.is_error_message_list_doc)
                         (Obj.magic
                            [FStarC_Errors_Msg.text
                               (FStarC_Format.fmt1
                                  "Polymonadic subcomp (%s in this case) is an experimental feature;it is subject to some redesign in the future. Please keep us informed (on github etc.) about how you are using it"
                                  combinator_name)]);
                       (let uu___7 =
                          let uu___8 =
                            FStarC_Syntax_Subst.close_univ_vars us1 k in
                          (us1, uu___8) in
                        ((us1, t), uu___7, kind)))))))
