open Prims
type 't mm = Prims.bool -> ('t * Prims.bool)
let op_let_Question (f : 't mm) (g : 't -> 's mm) : 's mm=
  fun b ->
    let uu___ = f b in
    match uu___ with | (t1, b1) -> let uu___1 = g t1 in uu___1 b1
let ret (x : 't) : 't mm= fun b -> (x, b)
let should_memo : Prims.bool mm= fun b -> (b, b)
let no_memo : unit mm= fun uu___ -> ((), false)
let maybe_memoize (h : 'a FStarC_Syntax_Syntax.syntax)
  (f : 'a FStarC_Syntax_Syntax.syntax -> FStarC_Hash.hash_code mm) :
  FStarC_Hash.hash_code mm=
  fun should_memo1 ->
    if should_memo1
    then
      let uu___ = FStarC_Effect.op_Bang h.FStarC_Syntax_Syntax.hash_code in
      match uu___ with
      | FStar_Pervasives_Native.Some c -> (c, should_memo1)
      | FStar_Pervasives_Native.None ->
          let uu___1 = let uu___2 = f h in uu___2 should_memo1 in
          (match uu___1 with
           | (c, should_memo2) ->
               (if should_memo2
                then
                  FStarC_Effect.op_Colon_Equals
                    h.FStarC_Syntax_Syntax.hash_code
                    (FStar_Pervasives_Native.Some c)
                else ();
                (c, should_memo2)))
    else (let uu___1 = f h in uu___1 should_memo1)
let of_int (i : Prims.int) : FStarC_Hash.hash_code mm=
  let uu___ = FStarC_Hash.of_int i in ret uu___
let of_string (s : Prims.string) : FStarC_Hash.hash_code mm=
  let uu___ = FStarC_Hash.of_string s in ret uu___
let mix (f : FStarC_Hash.hash_code mm) (g : FStarC_Hash.hash_code mm) :
  FStarC_Hash.hash_code mm=
  fun b ->
    let uu___ = f b in
    match uu___ with
    | (x, b0) ->
        let uu___1 = g b in
        (match uu___1 with
         | (y, b1) ->
             let uu___2 = FStarC_Hash.mix x y in (uu___2, (b0 && b1)))
let nil_hc : FStarC_Hash.hash_code mm= of_int (Prims.of_int (1229))
let cons_hc : FStarC_Hash.hash_code mm= of_int (Prims.of_int (1231))
let mix_list (l : FStarC_Hash.hash_code mm Prims.list) :
  FStarC_Hash.hash_code mm= FStarC_List.fold_right mix l nil_hc
let mix_list_lit :
  FStarC_Hash.hash_code mm Prims.list -> FStarC_Hash.hash_code mm= mix_list
let hash_list (h : 'a -> FStarC_Hash.hash_code mm) (ts : 'a Prims.list) :
  FStarC_Hash.hash_code mm=
  let uu___ = FStarC_List.map h ts in mix_list uu___
let hash_option (h : 'a -> FStarC_Hash.hash_code mm)
  (o : 'a FStar_Pervasives_Native.option) : FStarC_Hash.hash_code mm=
  match o with
  | FStar_Pervasives_Native.None ->
      let uu___ = FStarC_Hash.of_int (Prims.of_int (1237)) in ret uu___
  | FStar_Pervasives_Native.Some o1 ->
      let uu___ =
        let uu___1 = FStarC_Hash.of_int (Prims.of_int (1249)) in ret uu___1 in
      let uu___1 = h o1 in mix uu___ uu___1
let hash_doc (d : FStar_Pprint.document) : FStarC_Hash.hash_code mm=
  let uu___ =
    FStarC_Pprint.pretty_string (FStarC_Util.float_of_string "1.0")
      (Prims.of_int (80)) d in
  of_string uu___
let hash_doc_list (ds : FStar_Pprint.document Prims.list) :
  FStarC_Hash.hash_code mm= hash_list hash_doc ds
let hash_pair (h : 'a -> FStarC_Hash.hash_code mm)
  (i : 'b -> FStarC_Hash.hash_code mm) (x : ('a * 'b)) :
  FStarC_Hash.hash_code mm=
  let uu___ = h (FStar_Pervasives_Native.fst x) in
  let uu___1 = i (FStar_Pervasives_Native.snd x) in mix uu___ uu___1
let rec hash_term (t : FStarC_Syntax_Syntax.term) : FStarC_Hash.hash_code mm=
  maybe_memoize t hash_term'
and hash_comp (c : FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax) :
  FStarC_Hash.hash_code mm= maybe_memoize c hash_comp'
and hash_term' (t : FStarC_Syntax_Syntax.term) : FStarC_Hash.hash_code mm=
  let uu___ =
    let uu___1 = FStarC_Syntax_Subst.compress t in
    uu___1.FStarC_Syntax_Syntax.n in
  match uu___ with
  | FStarC_Syntax_Syntax.Tm_bvar bv ->
      let uu___1 = of_int (Prims.of_int (3)) in
      let uu___2 = of_int bv.FStarC_Syntax_Syntax.index in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_name bv ->
      let uu___1 = of_int (Prims.of_int (5)) in
      let uu___2 = of_int bv.FStarC_Syntax_Syntax.index in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_fvar fv ->
      let uu___1 = of_int (Prims.of_int (7)) in
      let uu___2 = hash_fv fv in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_uinst (t1, us) ->
      let uu___1 = of_int (Prims.of_int (11)) in
      let uu___2 =
        let uu___3 = hash_term t1 in
        let uu___4 = hash_list hash_universe us in mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_constant sc ->
      let uu___1 = of_int (Prims.of_int (13)) in
      let uu___2 = hash_constant sc in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_type u ->
      let uu___1 = of_int (Prims.of_int (17)) in
      let uu___2 = hash_universe u in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_abs
      { FStarC_Syntax_Syntax.bs = bs; FStarC_Syntax_Syntax.body = t1;
        FStarC_Syntax_Syntax.rc_opt = rcopt;_}
      ->
      let uu___1 = of_int (Prims.of_int (19)) in
      let uu___2 =
        let uu___3 = hash_list hash_binder bs in
        let uu___4 =
          let uu___5 = hash_term t1 in
          let uu___6 = hash_option hash_rc rcopt in mix uu___5 uu___6 in
        mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_arrow
      { FStarC_Syntax_Syntax.bs1 = bs; FStarC_Syntax_Syntax.comp = c;_} ->
      let uu___1 = of_int (Prims.of_int (23)) in
      let uu___2 =
        let uu___3 = hash_list hash_binder bs in
        let uu___4 = hash_comp c in mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_refine
      { FStarC_Syntax_Syntax.b = b; FStarC_Syntax_Syntax.phi = t1;_} ->
      let uu___1 = of_int (Prims.of_int (29)) in
      let uu___2 =
        let uu___3 = hash_bv b in
        let uu___4 = hash_term t1 in mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_app uu___1 ->
      let uu___2 = FStarC_Syntax_Util.head_and_args_full t in
      (match uu___2 with
       | (hd, args) ->
           let uu___3 = hash_term hd in
           let uu___4 = hash_list hash_arg args in mix uu___3 uu___4)
  | FStarC_Syntax_Syntax.Tm_match
      { FStarC_Syntax_Syntax.scrutinee = t1;
        FStarC_Syntax_Syntax.ret_opt = asc_opt;
        FStarC_Syntax_Syntax.brs = branches;
        FStarC_Syntax_Syntax.rc_opt1 = rcopt;_}
      ->
      let uu___1 = of_int (Prims.of_int (37)) in
      let uu___2 =
        let uu___3 = hash_option hash_match_returns asc_opt in
        let uu___4 =
          let uu___5 =
            let uu___6 = hash_term t1 in
            let uu___7 = hash_list hash_branch branches in mix uu___6 uu___7 in
          let uu___6 = hash_option hash_rc rcopt in mix uu___5 uu___6 in
        mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_ascribed
      { FStarC_Syntax_Syntax.tm = t1; FStarC_Syntax_Syntax.asc = a;
        FStarC_Syntax_Syntax.eff_opt = lopt;_}
      ->
      let uu___1 = of_int (Prims.of_int (43)) in
      let uu___2 =
        let uu___3 = hash_term t1 in
        let uu___4 =
          let uu___5 = hash_ascription a in
          let uu___6 = hash_option hash_lid lopt in mix uu___5 uu___6 in
        mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_let
      { FStarC_Syntax_Syntax.lbs = (false, lb::[]);
        FStarC_Syntax_Syntax.body1 = t1;_}
      ->
      let uu___1 = of_int (Prims.of_int (47)) in
      let uu___2 =
        let uu___3 = hash_lb lb in
        let uu___4 = hash_term t1 in mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_let
      { FStarC_Syntax_Syntax.lbs = (uu___1, lbs);
        FStarC_Syntax_Syntax.body1 = t1;_}
      ->
      let uu___2 = of_int (Prims.of_int (51)) in
      let uu___3 =
        let uu___4 = hash_list hash_lb lbs in
        let uu___5 = hash_term t1 in mix uu___4 uu___5 in
      mix uu___2 uu___3
  | FStarC_Syntax_Syntax.Tm_uvar uv ->
      let uu___1 = of_int (Prims.of_int (53)) in
      let uu___2 = hash_uvar uv in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_meta
      { FStarC_Syntax_Syntax.tm2 = t1; FStarC_Syntax_Syntax.meta = m;_} ->
      let uu___1 = of_int (Prims.of_int (61)) in
      let uu___2 =
        let uu___3 = hash_term t1 in
        let uu___4 = hash_meta m in mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_lazy li ->
      let uu___1 = of_int (Prims.of_int (67)) in
      let uu___2 = hash_lazyinfo li in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_quoted (t1, qi) ->
      let uu___1 = of_int (Prims.of_int (71)) in
      let uu___2 =
        let uu___3 = hash_term t1 in
        let uu___4 = hash_quoteinfo qi in mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Tm_unknown -> of_int (Prims.of_int (73))
  | FStarC_Syntax_Syntax.Tm_delayed uu___1 -> failwith "Impossible"
and hash_comp' (c : FStarC_Syntax_Syntax.comp) : FStarC_Hash.hash_code mm=
  match c.FStarC_Syntax_Syntax.n with
  | FStarC_Syntax_Syntax.Total t ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (811)) in
        let uu___2 = let uu___3 = hash_term t in [uu___3] in uu___1 :: uu___2 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.GTotal t ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (821)) in
        let uu___2 = let uu___3 = hash_term t in [uu___3] in uu___1 :: uu___2 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Comp ct ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (823)) in
        let uu___2 =
          let uu___3 =
            hash_list hash_universe ct.FStarC_Syntax_Syntax.comp_univs in
          let uu___4 =
            let uu___5 = hash_lid ct.FStarC_Syntax_Syntax.effect_name in
            let uu___6 =
              let uu___7 = hash_term ct.FStarC_Syntax_Syntax.result_typ in
              let uu___8 =
                let uu___9 =
                  hash_list hash_arg ct.FStarC_Syntax_Syntax.effect_args in
                let uu___10 =
                  let uu___11 =
                    hash_list hash_flag ct.FStarC_Syntax_Syntax.flags in
                  [uu___11] in
                uu___9 :: uu___10 in
              uu___7 :: uu___8 in
            uu___5 :: uu___6 in
          uu___3 :: uu___4 in
        uu___1 :: uu___2 in
      mix_list_lit uu___
and hash_lb (lb : FStarC_Syntax_Syntax.letbinding) :
  FStarC_Hash.hash_code mm=
  let uu___ =
    let uu___1 = of_int (Prims.of_int (79)) in
    let uu___2 =
      let uu___3 = hash_lbname lb.FStarC_Syntax_Syntax.lbname in
      let uu___4 =
        let uu___5 = hash_list hash_ident lb.FStarC_Syntax_Syntax.lbunivs in
        let uu___6 =
          let uu___7 = hash_term lb.FStarC_Syntax_Syntax.lbtyp in
          let uu___8 =
            let uu___9 = hash_lid lb.FStarC_Syntax_Syntax.lbeff in
            let uu___10 =
              let uu___11 = hash_term lb.FStarC_Syntax_Syntax.lbdef in
              let uu___12 =
                let uu___13 =
                  hash_list hash_term lb.FStarC_Syntax_Syntax.lbattrs in
                [uu___13] in
              uu___11 :: uu___12 in
            uu___9 :: uu___10 in
          uu___7 :: uu___8 in
        uu___5 :: uu___6 in
      uu___3 :: uu___4 in
    uu___1 :: uu___2 in
  mix_list_lit uu___
and hash_match_returns
  (uu___ :
    (FStarC_Syntax_Syntax.binder *
      ((FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax,
      FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax)
      FStar_Pervasives.either * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax FStar_Pervasives_Native.option *
      Prims.bool)))
  : FStarC_Hash.hash_code mm=
  match uu___ with
  | (b, asc) ->
      let uu___1 = hash_binder b in
      let uu___2 = hash_ascription asc in mix uu___1 uu___2
and hash_branch
  (b :
    (FStarC_Syntax_Syntax.pat' FStarC_Syntax_Syntax.withinfo_t *
      FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax
      FStar_Pervasives_Native.option * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax))
  : FStarC_Hash.hash_code mm=
  let uu___ = b in
  match uu___ with
  | (p, topt, t) ->
      let uu___1 =
        let uu___2 = of_int (Prims.of_int (83)) in
        let uu___3 =
          let uu___4 = hash_pat p in
          let uu___5 =
            let uu___6 = hash_option hash_term topt in
            let uu___7 = let uu___8 = hash_term t in [uu___8] in uu___6 ::
              uu___7 in
          uu___4 :: uu___5 in
        uu___2 :: uu___3 in
      mix_list_lit uu___1
and hash_pat (p : FStarC_Syntax_Syntax.pat' FStarC_Syntax_Syntax.withinfo_t)
  : FStarC_Hash.hash_code mm=
  match p.FStarC_Syntax_Syntax.v with
  | FStarC_Syntax_Syntax.Pat_constant c ->
      let uu___ = of_int (Prims.of_int (89)) in
      let uu___1 = hash_constant c in mix uu___ uu___1
  | FStarC_Syntax_Syntax.Pat_cons (fv, us, args) ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (97)) in
        let uu___2 =
          let uu___3 = hash_fv fv in
          let uu___4 =
            let uu___5 = hash_option (hash_list hash_universe) us in
            let uu___6 =
              let uu___7 = hash_list (hash_pair hash_pat hash_bool) args in
              [uu___7] in
            uu___5 :: uu___6 in
          uu___3 :: uu___4 in
        uu___1 :: uu___2 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Pat_var bv ->
      let uu___ = of_int (Prims.of_int (101)) in
      let uu___1 = hash_bv bv in mix uu___ uu___1
  | FStarC_Syntax_Syntax.Pat_dot_term t ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (107)) in
        let uu___2 = let uu___3 = hash_option hash_term t in [uu___3] in
        uu___1 :: uu___2 in
      mix_list_lit uu___
and hash_bv (b : FStarC_Syntax_Syntax.bv) : FStarC_Hash.hash_code mm=
  hash_term b.FStarC_Syntax_Syntax.sort
and hash_fv (fv : FStarC_Syntax_Syntax.fv) : FStarC_Hash.hash_code mm=
  let uu___ = FStarC_Ident.string_of_lid fv.FStarC_Syntax_Syntax.fv_name in
  of_string uu___
and hash_binder (b : FStarC_Syntax_Syntax.binder) : FStarC_Hash.hash_code mm=
  let uu___ =
    let uu___1 = hash_bv b.FStarC_Syntax_Syntax.binder_bv in
    let uu___2 =
      let uu___3 = hash_option hash_bqual b.FStarC_Syntax_Syntax.binder_qual in
      let uu___4 =
        let uu___5 = hash_list hash_term b.FStarC_Syntax_Syntax.binder_attrs in
        [uu___5] in
      uu___3 :: uu___4 in
    uu___1 :: uu___2 in
  mix_list_lit uu___
and hash_universe (uu___ : FStarC_Syntax_Syntax.universe) :
  FStarC_Hash.hash_code mm=
  match uu___ with
  | FStarC_Syntax_Syntax.U_zero -> of_int (Prims.of_int (179))
  | FStarC_Syntax_Syntax.U_succ u ->
      let uu___1 = of_int (Prims.of_int (181)) in
      let uu___2 = hash_universe u in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.U_max us ->
      let uu___1 = of_int (Prims.of_int (191)) in
      let uu___2 = hash_list hash_universe us in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.U_bvar i ->
      let uu___1 = of_int (Prims.of_int (193)) in
      let uu___2 = of_int i in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.U_name i ->
      let uu___1 = of_int (Prims.of_int (197)) in
      let uu___2 = hash_ident i in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.U_unif uv ->
      let uu___1 = of_int (Prims.of_int (199)) in
      let uu___2 = hash_universe_uvar uv in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.U_unknown -> of_int (Prims.of_int (211))
and hash_arg
  (uu___ :
    (FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax *
      FStarC_Syntax_Syntax.arg_qualifier FStar_Pervasives_Native.option))
  : FStarC_Hash.hash_code mm=
  match uu___ with
  | (t, aq) ->
      let uu___1 = hash_term t in
      let uu___2 = hash_option hash_arg_qualifier aq in mix uu___1 uu___2
and hash_arg_qualifier (aq : FStarC_Syntax_Syntax.arg_qualifier) :
  FStarC_Hash.hash_code mm=
  let uu___ = hash_bool aq.FStarC_Syntax_Syntax.aqual_implicit in
  let uu___1 = hash_list hash_term aq.FStarC_Syntax_Syntax.aqual_attributes in
  mix uu___ uu___1
and hash_bqual (uu___ : FStarC_Syntax_Syntax.binder_qualifier) :
  FStarC_Hash.hash_code mm=
  match uu___ with
  | FStarC_Syntax_Syntax.Implicit true -> of_int (Prims.of_int (419))
  | FStarC_Syntax_Syntax.Implicit false -> of_int (Prims.of_int (421))
  | FStarC_Syntax_Syntax.Meta t ->
      let uu___1 = of_int (Prims.of_int (431)) in
      let uu___2 = hash_term t in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Equality -> of_int (Prims.of_int (433))
and hash_uvar
  (uu___ :
    (FStarC_Syntax_Syntax.ctx_uvar * (FStarC_Syntax_Syntax.subst_elt
      Prims.list Prims.list * FStarC_Syntax_Syntax.maybe_set_use_range)))
  : FStarC_Hash.hash_code mm=
  match uu___ with
  | (u, uu___1) ->
      let uu___2 =
        FStarC_Syntax_Unionfind.uvar_id u.FStarC_Syntax_Syntax.ctx_uvar_head in
      of_int uu___2
and hash_universe_uvar
  (u :
    (FStarC_Syntax_Syntax.universe FStar_Pervasives_Native.option
      FStarC_Unionfind.p_uvar * FStarC_Syntax_Syntax.version *
      FStarC_Range_Type.range))
  : FStarC_Hash.hash_code mm=
  let uu___ = FStarC_Syntax_Unionfind.univ_uvar_id u in of_int uu___
and hash_ascription
  (uu___ :
    ((FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax,
      FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax)
      FStar_Pervasives.either * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax FStar_Pervasives_Native.option *
      Prims.bool))
  : FStarC_Hash.hash_code mm=
  match uu___ with
  | (a, to1, b) ->
      let uu___1 =
        match a with
        | FStar_Pervasives.Inl t -> hash_term t
        | FStar_Pervasives.Inr c -> hash_comp c in
      let uu___2 = hash_option hash_term to1 in mix uu___1 uu___2
and hash_bool (b : Prims.bool) : FStarC_Hash.hash_code mm=
  if b then of_int (Prims.of_int (307)) else of_int (Prims.of_int (311))
and hash_constant (uu___ : FStarC_Syntax_Syntax.sconst) :
  FStarC_Hash.hash_code mm=
  match uu___ with
  | FStarC_Const.Const_effect -> of_int (Prims.of_int (283))
  | FStarC_Const.Const_unit -> of_int (Prims.of_int (293))
  | FStarC_Const.Const_bool b -> hash_bool b
  | FStarC_Const.Const_int (s, o) ->
      let uu___1 = of_int (Prims.of_int (313)) in
      let uu___2 =
        let uu___3 = of_string s in
        let uu___4 = hash_option hash_sw o in mix uu___3 uu___4 in
      mix uu___1 uu___2
  | FStarC_Const.Const_char c ->
      let uu___1 = of_int (Prims.of_int (317)) in
      let uu___2 = of_int (FStar_Char.int_of_char c) in mix uu___1 uu___2
  | FStarC_Const.Const_real s ->
      let uu___1 = of_int (Prims.of_int (337)) in
      let uu___2 = of_string s in mix uu___1 uu___2
  | FStarC_Const.Const_string (s, uu___1) ->
      let uu___2 = of_int (Prims.of_int (349)) in
      let uu___3 = of_string s in mix uu___2 uu___3
  | FStarC_Const.Const_range_of -> of_int (Prims.of_int (353))
  | FStarC_Const.Const_set_range_of -> of_int (Prims.of_int (359))
  | FStarC_Const.Const_range r ->
      let uu___1 = of_int (Prims.of_int (367)) in
      let uu___2 =
        let uu___3 = FStarC_Range_Ops.string_of_range r in of_string uu___3 in
      mix uu___1 uu___2
  | FStarC_Const.Const_reify uu___1 -> of_int (Prims.of_int (367))
  | FStarC_Const.Const_reflect l ->
      let uu___1 = of_int (Prims.of_int (373)) in
      let uu___2 = hash_lid l in mix uu___1 uu___2
and hash_sw (uu___ : (FStarC_Const.signedness * FStarC_Const.width)) :
  FStarC_Hash.hash_code mm=
  match uu___ with
  | (s, w) ->
      let uu___1 =
        match s with
        | FStarC_Const.Unsigned -> of_int (Prims.of_int (547))
        | FStarC_Const.Signed -> of_int (Prims.of_int (557)) in
      let uu___2 =
        match w with
        | FStarC_Const.Int8 -> of_int (Prims.of_int (563))
        | FStarC_Const.Int16 -> of_int (Prims.of_int (569))
        | FStarC_Const.Int32 -> of_int (Prims.of_int (571))
        | FStarC_Const.Int64 -> of_int (Prims.of_int (577))
        | FStarC_Const.Sizet -> of_int (Prims.of_int (583)) in
      mix uu___1 uu___2
and hash_ident (i : FStarC_Syntax_Syntax.univ_name) :
  FStarC_Hash.hash_code mm=
  let uu___ = FStarC_Ident.string_of_id i in of_string uu___
and hash_lid (l : FStarC_Ident.lident) : FStarC_Hash.hash_code mm=
  let uu___ = FStarC_Ident.string_of_lid l in of_string uu___
and hash_lbname
  (l :
    (FStarC_Syntax_Syntax.bv, FStarC_Syntax_Syntax.fv)
      FStar_Pervasives.either)
  : FStarC_Hash.hash_code mm=
  match l with
  | FStar_Pervasives.Inl bv -> hash_bv bv
  | FStar_Pervasives.Inr fv -> hash_fv fv
and hash_rc (rc : FStarC_Syntax_Syntax.residual_comp) :
  FStarC_Hash.hash_code mm=
  let uu___ =
    let uu___1 = hash_lid rc.FStarC_Syntax_Syntax.residual_effect in
    let uu___2 =
      let uu___3 = hash_option hash_term rc.FStarC_Syntax_Syntax.residual_typ in
      let uu___4 =
        let uu___5 =
          hash_list hash_flag rc.FStarC_Syntax_Syntax.residual_flags in
        [uu___5] in
      uu___3 :: uu___4 in
    uu___1 :: uu___2 in
  mix_list_lit uu___
and hash_flag (uu___ : FStarC_Syntax_Syntax.cflag) :
  FStarC_Hash.hash_code mm=
  match uu___ with
  | FStarC_Syntax_Syntax.TOTAL -> of_int (Prims.of_int (947))
  | FStarC_Syntax_Syntax.MLEFFECT -> of_int (Prims.of_int (953))
  | FStarC_Syntax_Syntax.LEMMA -> of_int (Prims.of_int (967))
  | FStarC_Syntax_Syntax.RETURN -> of_int (Prims.of_int (971))
  | FStarC_Syntax_Syntax.PARTIAL_RETURN -> of_int (Prims.of_int (977))
  | FStarC_Syntax_Syntax.SOMETRIVIAL -> of_int (Prims.of_int (983))
  | FStarC_Syntax_Syntax.TRIVIAL_POSTCONDITION -> of_int (Prims.of_int (991))
  | FStarC_Syntax_Syntax.SHOULD_NOT_INLINE -> of_int (Prims.of_int (997))
  | FStarC_Syntax_Syntax.CPS -> of_int (Prims.of_int (1009))
  | FStarC_Syntax_Syntax.DECREASES (FStarC_Syntax_Syntax.Decreases_lex ts) ->
      let uu___1 = of_int (Prims.of_int (1013)) in
      let uu___2 = hash_list hash_term ts in mix uu___1 uu___2
  | FStarC_Syntax_Syntax.DECREASES (FStarC_Syntax_Syntax.Decreases_wf
      (t0, t1)) ->
      let uu___1 = of_int (Prims.of_int (2341)) in
      let uu___2 = hash_list hash_term [t0; t1] in mix uu___1 uu___2
and hash_meta (m : FStarC_Syntax_Syntax.metadata) : FStarC_Hash.hash_code mm=
  match m with
  | FStarC_Syntax_Syntax.Meta_pattern (ts, args) ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (1019)) in
        let uu___2 =
          let uu___3 = hash_list hash_term ts in
          let uu___4 =
            let uu___5 = hash_list (hash_list hash_arg) args in [uu___5] in
          uu___3 :: uu___4 in
        uu___1 :: uu___2 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Meta_named l ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (1021)) in
        let uu___2 = let uu___3 = hash_lid l in [uu___3] in uu___1 :: uu___2 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Meta_labeled (s, r, uu___) ->
      let uu___1 =
        let uu___2 = of_int (Prims.of_int (1031)) in
        let uu___3 =
          let uu___4 = hash_doc_list s in
          let uu___5 =
            let uu___6 =
              let uu___7 = FStarC_Range_Ops.string_of_range r in
              of_string uu___7 in
            [uu___6] in
          uu___4 :: uu___5 in
        uu___2 :: uu___3 in
      mix_list_lit uu___1
  | FStarC_Syntax_Syntax.Meta_desugared msi ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (1033)) in
        let uu___2 = let uu___3 = hash_meta_source_info msi in [uu___3] in
        uu___1 :: uu___2 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Meta_monadic (m1, t) ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (1039)) in
        let uu___2 =
          let uu___3 = hash_lid m1 in
          let uu___4 = let uu___5 = hash_term t in [uu___5] in uu___3 ::
            uu___4 in
        uu___1 :: uu___2 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Meta_monadic_lift (m0, m1, t) ->
      let uu___ =
        let uu___1 = of_int (Prims.of_int (1069)) in
        let uu___2 =
          let uu___3 = hash_lid m0 in
          let uu___4 =
            let uu___5 = hash_lid m1 in
            let uu___6 = let uu___7 = hash_term t in [uu___7] in uu___5 ::
              uu___6 in
          uu___3 :: uu___4 in
        uu___1 :: uu___2 in
      mix_list_lit uu___
and hash_meta_source_info (m : FStarC_Syntax_Syntax.meta_source_info) :
  FStarC_Hash.hash_code mm=
  match m with
  | FStarC_Syntax_Syntax.Sequence -> of_int (Prims.of_int (1049))
  | FStarC_Syntax_Syntax.Primop -> of_int (Prims.of_int (1051))
  | FStarC_Syntax_Syntax.Masked_effect -> of_int (Prims.of_int (1061))
  | FStarC_Syntax_Syntax.Meta_smt_pat -> of_int (Prims.of_int (1063))
  | FStarC_Syntax_Syntax.Machine_integer sw ->
      let uu___ = of_int (Prims.of_int (1069)) in
      let uu___1 = hash_sw sw in mix uu___ uu___1
and hash_lazyinfo (li : FStarC_Syntax_Syntax.lazyinfo) :
  FStarC_Hash.hash_code mm= of_int Prims.int_zero
and hash_quoteinfo (qi : FStarC_Syntax_Syntax.quoteinfo) :
  FStarC_Hash.hash_code mm=
  let uu___ =
    hash_bool
      (qi.FStarC_Syntax_Syntax.qkind = FStarC_Syntax_Syntax.Quote_static) in
  let uu___1 =
    hash_list hash_term
      (FStar_Pervasives_Native.snd qi.FStarC_Syntax_Syntax.antiquotations) in
  mix uu___ uu___1
let rec equal_list :
  'uuuuu 'uuuuu1 .
    ('uuuuu -> 'uuuuu1 -> Prims.bool) ->
      'uuuuu Prims.list -> 'uuuuu1 Prims.list -> Prims.bool
  =
  fun f l1 l2 ->
    match (l1, l2) with
    | ([], []) -> true
    | (h1::t1, h2::t2) -> (f h1 h2) && (equal_list f t1 t2)
    | uu___ -> false
let equal_opt (f : 'uuuuu -> 'uuuuu1 -> Prims.bool)
  (o1 : 'uuuuu FStar_Pervasives_Native.option)
  (o2 : 'uuuuu1 FStar_Pervasives_Native.option) : Prims.bool=
  match (o1, o2) with
  | (FStar_Pervasives_Native.None, FStar_Pervasives_Native.None) -> true
  | (FStar_Pervasives_Native.Some a, FStar_Pervasives_Native.Some b) -> f a b
  | uu___ -> false
let equal_pair (f : 'uuuuu -> 'uuuuu1 -> Prims.bool)
  (g : 'uuuuu2 -> 'uuuuu3 -> Prims.bool) (uu___ : ('uuuuu * 'uuuuu2))
  (uu___1 : ('uuuuu1 * 'uuuuu3)) : Prims.bool=
  match (uu___, uu___1) with | ((x1, y1), (x2, y2)) -> (f x1 x2) && (g y1 y2)
let equal_poly (x : 'uuuuu) (y : 'uuuuu) : Prims.bool= x = y
let ext_hash_term (t : FStarC_Syntax_Syntax.term) : FStarC_Hash.hash_code=
  let uu___ = let uu___1 = hash_term t in uu___1 true in
  FStar_Pervasives_Native.fst uu___
let ext_hash_term_no_memo (t : FStarC_Syntax_Syntax.term) :
  FStarC_Hash.hash_code=
  let uu___ = let uu___1 = hash_term t in uu___1 false in
  FStar_Pervasives_Native.fst uu___
let rec equal_term (t1 : FStarC_Syntax_Syntax.term)
  (t2 : FStarC_Syntax_Syntax.term) : Prims.bool=
  let uu___ = FStarC_Util.physical_equality t1 t2 in
  if uu___
  then true
  else
    (let uu___2 =
       FStarC_Util.physical_equality t1.FStarC_Syntax_Syntax.n
         t2.FStarC_Syntax_Syntax.n in
     if uu___2
     then true
     else
       (let uu___4 =
          let uu___5 = ext_hash_term t1 in
          let uu___6 = ext_hash_term t2 in uu___5 <> uu___6 in
        if uu___4
        then false
        else
          (let uu___6 =
             let uu___7 =
               let uu___8 = FStarC_Syntax_Subst.compress t1 in
               uu___8.FStarC_Syntax_Syntax.n in
             let uu___8 =
               let uu___9 = FStarC_Syntax_Subst.compress t2 in
               uu___9.FStarC_Syntax_Syntax.n in
             (uu___7, uu___8) in
           match uu___6 with
           | (FStarC_Syntax_Syntax.Tm_bvar x, FStarC_Syntax_Syntax.Tm_bvar y)
               -> x.FStarC_Syntax_Syntax.index = y.FStarC_Syntax_Syntax.index
           | (FStarC_Syntax_Syntax.Tm_name x, FStarC_Syntax_Syntax.Tm_name y)
               -> x.FStarC_Syntax_Syntax.index = y.FStarC_Syntax_Syntax.index
           | (FStarC_Syntax_Syntax.Tm_fvar f, FStarC_Syntax_Syntax.Tm_fvar g)
               -> equal_fv f g
           | (FStarC_Syntax_Syntax.Tm_uinst (t11, u1),
              FStarC_Syntax_Syntax.Tm_uinst (t21, u2)) ->
               (equal_term t11 t21) && (equal_list equal_universe u1 u2)
           | (FStarC_Syntax_Syntax.Tm_constant c1,
              FStarC_Syntax_Syntax.Tm_constant c2) -> equal_constant c1 c2
           | (FStarC_Syntax_Syntax.Tm_type u1, FStarC_Syntax_Syntax.Tm_type
              u2) -> equal_universe u1 u2
           | (FStarC_Syntax_Syntax.Tm_abs
              { FStarC_Syntax_Syntax.bs = bs1;
                FStarC_Syntax_Syntax.body = t11;
                FStarC_Syntax_Syntax.rc_opt = rc1;_},
              FStarC_Syntax_Syntax.Tm_abs
              { FStarC_Syntax_Syntax.bs = bs2;
                FStarC_Syntax_Syntax.body = t21;
                FStarC_Syntax_Syntax.rc_opt = rc2;_})
               ->
               ((equal_list equal_binder bs1 bs2) && (equal_term t11 t21)) &&
                 (equal_opt equal_rc rc1 rc2)
           | (FStarC_Syntax_Syntax.Tm_arrow
              { FStarC_Syntax_Syntax.bs1 = bs1;
                FStarC_Syntax_Syntax.comp = c1;_},
              FStarC_Syntax_Syntax.Tm_arrow
              { FStarC_Syntax_Syntax.bs1 = bs2;
                FStarC_Syntax_Syntax.comp = c2;_})
               -> (equal_list equal_binder bs1 bs2) && (equal_comp c1 c2)
           | (FStarC_Syntax_Syntax.Tm_refine
              { FStarC_Syntax_Syntax.b = b1;
                FStarC_Syntax_Syntax.phi = t11;_},
              FStarC_Syntax_Syntax.Tm_refine
              { FStarC_Syntax_Syntax.b = b2;
                FStarC_Syntax_Syntax.phi = t21;_})
               -> (equal_bv b1 b2) && (equal_term t11 t21)
           | (FStarC_Syntax_Syntax.Tm_app uu___7, FStarC_Syntax_Syntax.Tm_app
              uu___8) ->
               let uu___9 = FStarC_Syntax_Util.head_and_args_full t1 in
               (match uu___9 with
                | (hd1, args1) ->
                    let uu___10 = FStarC_Syntax_Util.head_and_args_full t2 in
                    (match uu___10 with
                     | (hd2, args2) ->
                         (equal_term hd1 hd2) &&
                           (equal_list equal_arg args1 args2)))
           | (FStarC_Syntax_Syntax.Tm_match
              { FStarC_Syntax_Syntax.scrutinee = t11;
                FStarC_Syntax_Syntax.ret_opt = asc_opt1;
                FStarC_Syntax_Syntax.brs = bs1;
                FStarC_Syntax_Syntax.rc_opt1 = ropt1;_},
              FStarC_Syntax_Syntax.Tm_match
              { FStarC_Syntax_Syntax.scrutinee = t21;
                FStarC_Syntax_Syntax.ret_opt = asc_opt2;
                FStarC_Syntax_Syntax.brs = bs2;
                FStarC_Syntax_Syntax.rc_opt1 = ropt2;_})
               ->
               (((equal_term t11 t21) &&
                   (equal_opt equal_match_returns asc_opt1 asc_opt2))
                  && (equal_list equal_branch bs1 bs2))
                 && (equal_opt equal_rc ropt1 ropt2)
           | (FStarC_Syntax_Syntax.Tm_ascribed
              { FStarC_Syntax_Syntax.tm = t11; FStarC_Syntax_Syntax.asc = a1;
                FStarC_Syntax_Syntax.eff_opt = l1;_},
              FStarC_Syntax_Syntax.Tm_ascribed
              { FStarC_Syntax_Syntax.tm = t21; FStarC_Syntax_Syntax.asc = a2;
                FStarC_Syntax_Syntax.eff_opt = l2;_})
               ->
               ((equal_term t11 t21) && (equal_ascription a1 a2)) &&
                 (equal_opt FStarC_Ident.lid_equals l1 l2)
           | (FStarC_Syntax_Syntax.Tm_let
              { FStarC_Syntax_Syntax.lbs = (r1, lbs1);
                FStarC_Syntax_Syntax.body1 = t11;_},
              FStarC_Syntax_Syntax.Tm_let
              { FStarC_Syntax_Syntax.lbs = (r2, lbs2);
                FStarC_Syntax_Syntax.body1 = t21;_})
               ->
               ((r1 = r2) && (equal_list equal_letbinding lbs1 lbs2)) &&
                 (equal_term t11 t21)
           | (FStarC_Syntax_Syntax.Tm_uvar u1, FStarC_Syntax_Syntax.Tm_uvar
              u2) -> equal_uvar u1 u2
           | (FStarC_Syntax_Syntax.Tm_meta
              { FStarC_Syntax_Syntax.tm2 = t11;
                FStarC_Syntax_Syntax.meta = m1;_},
              FStarC_Syntax_Syntax.Tm_meta
              { FStarC_Syntax_Syntax.tm2 = t21;
                FStarC_Syntax_Syntax.meta = m2;_})
               -> (equal_term t11 t21) && (equal_meta m1 m2)
           | (FStarC_Syntax_Syntax.Tm_lazy l1, FStarC_Syntax_Syntax.Tm_lazy
              l2) -> equal_lazyinfo l1 l2
           | (FStarC_Syntax_Syntax.Tm_quoted (t11, q1),
              FStarC_Syntax_Syntax.Tm_quoted (t21, q2)) ->
               (equal_term t11 t21) && (equal_quoteinfo q1 q2)
           | (FStarC_Syntax_Syntax.Tm_unknown,
              FStarC_Syntax_Syntax.Tm_unknown) -> true
           | uu___7 -> false)))
and equal_comp (c1 : FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax)
  (c2 : FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax) : Prims.bool=
  let uu___ = FStarC_Util.physical_equality c1 c2 in
  if uu___
  then true
  else
    (match ((c1.FStarC_Syntax_Syntax.n), (c2.FStarC_Syntax_Syntax.n)) with
     | (FStarC_Syntax_Syntax.Total t1, FStarC_Syntax_Syntax.Total t2) ->
         equal_term t1 t2
     | (FStarC_Syntax_Syntax.GTotal t1, FStarC_Syntax_Syntax.GTotal t2) ->
         equal_term t1 t2
     | (FStarC_Syntax_Syntax.Comp ct1, FStarC_Syntax_Syntax.Comp ct2) ->
         ((((FStarC_Ident.lid_equals ct1.FStarC_Syntax_Syntax.effect_name
               ct2.FStarC_Syntax_Syntax.effect_name)
              &&
              (equal_list equal_universe ct1.FStarC_Syntax_Syntax.comp_univs
                 ct2.FStarC_Syntax_Syntax.comp_univs))
             &&
             (equal_term ct1.FStarC_Syntax_Syntax.result_typ
                ct2.FStarC_Syntax_Syntax.result_typ))
            &&
            (equal_list equal_arg ct1.FStarC_Syntax_Syntax.effect_args
               ct2.FStarC_Syntax_Syntax.effect_args))
           &&
           (equal_list equal_flag ct1.FStarC_Syntax_Syntax.flags
              ct2.FStarC_Syntax_Syntax.flags)
     | uu___2 -> false)
and equal_binder (b1 : FStarC_Syntax_Syntax.binder)
  (b2 : FStarC_Syntax_Syntax.binder) : Prims.bool=
  let uu___ = FStarC_Util.physical_equality b1 b2 in
  if uu___
  then true
  else
    ((equal_bv b1.FStarC_Syntax_Syntax.binder_bv
        b2.FStarC_Syntax_Syntax.binder_bv)
       &&
       (equal_bqual b1.FStarC_Syntax_Syntax.binder_qual
          b2.FStarC_Syntax_Syntax.binder_qual))
      &&
      (equal_list equal_term b1.FStarC_Syntax_Syntax.binder_attrs
         b2.FStarC_Syntax_Syntax.binder_attrs)
and equal_match_returns
  (uu___ :
    (FStarC_Syntax_Syntax.binder *
      ((FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax,
      FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax)
      FStar_Pervasives.either * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax FStar_Pervasives_Native.option *
      Prims.bool)))
  (uu___1 :
    (FStarC_Syntax_Syntax.binder *
      ((FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax,
      FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax)
      FStar_Pervasives.either * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax FStar_Pervasives_Native.option *
      Prims.bool)))
  : Prims.bool=
  match (uu___, uu___1) with
  | ((b1, asc1), (b2, asc2)) ->
      (equal_binder b1 b2) && (equal_ascription asc1 asc2)
and equal_ascription
  (x1 :
    ((FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax,
      FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax)
      FStar_Pervasives.either * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax FStar_Pervasives_Native.option *
      Prims.bool))
  (x2 :
    ((FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax,
      FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax)
      FStar_Pervasives.either * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax FStar_Pervasives_Native.option *
      Prims.bool))
  : Prims.bool=
  let uu___ = FStarC_Util.physical_equality x1 x2 in
  if uu___
  then true
  else
    (let uu___2 = x1 in
     match uu___2 with
     | (a1, t1, b1) ->
         let uu___3 = x2 in
         (match uu___3 with
          | (a2, t2, b2) ->
              ((match (a1, a2) with
                | (FStar_Pervasives.Inl t11, FStar_Pervasives.Inl t21) ->
                    equal_term t11 t21
                | (FStar_Pervasives.Inr c1, FStar_Pervasives.Inr c2) ->
                    equal_comp c1 c2
                | uu___4 -> false) && (equal_opt equal_term t1 t2)) &&
                (b1 = b2)))
and equal_letbinding (l1 : FStarC_Syntax_Syntax.letbinding)
  (l2 : FStarC_Syntax_Syntax.letbinding) : Prims.bool=
  let uu___ = FStarC_Util.physical_equality l1 l2 in
  if uu___
  then true
  else
    (((((equal_lbname l1.FStarC_Syntax_Syntax.lbname
           l2.FStarC_Syntax_Syntax.lbname)
          &&
          (equal_list FStarC_Ident.ident_equals
             l1.FStarC_Syntax_Syntax.lbunivs l2.FStarC_Syntax_Syntax.lbunivs))
         &&
         (equal_term l1.FStarC_Syntax_Syntax.lbtyp
            l2.FStarC_Syntax_Syntax.lbtyp))
        &&
        (FStarC_Ident.lid_equals l1.FStarC_Syntax_Syntax.lbeff
           l2.FStarC_Syntax_Syntax.lbeff))
       &&
       (equal_term l1.FStarC_Syntax_Syntax.lbdef
          l2.FStarC_Syntax_Syntax.lbdef))
      &&
      (equal_list equal_term l1.FStarC_Syntax_Syntax.lbattrs
         l2.FStarC_Syntax_Syntax.lbattrs)
and equal_uvar
  (uu___ :
    (FStarC_Syntax_Syntax.ctx_uvar * (FStarC_Syntax_Syntax.subst_elt
      Prims.list Prims.list * FStarC_Syntax_Syntax.maybe_set_use_range)))
  (uu___1 :
    (FStarC_Syntax_Syntax.ctx_uvar * (FStarC_Syntax_Syntax.subst_elt
      Prims.list Prims.list * FStarC_Syntax_Syntax.maybe_set_use_range)))
  : Prims.bool=
  match (uu___, uu___1) with
  | ((u1, (s1, uu___2)), (u2, (s2, uu___3))) ->
      (FStarC_Syntax_Unionfind.equiv u1.FStarC_Syntax_Syntax.ctx_uvar_head
         u2.FStarC_Syntax_Syntax.ctx_uvar_head)
        && (equal_list (equal_list equal_subst_elt) s1 s2)
and equal_bv (b1 : FStarC_Syntax_Syntax.bv) (b2 : FStarC_Syntax_Syntax.bv) :
  Prims.bool=
  let uu___ = FStarC_Util.physical_equality b1 b2 in
  if uu___
  then true
  else
    (FStarC_Ident.ident_equals b1.FStarC_Syntax_Syntax.ppname
       b2.FStarC_Syntax_Syntax.ppname)
      &&
      (equal_term b1.FStarC_Syntax_Syntax.sort b2.FStarC_Syntax_Syntax.sort)
and equal_fv (f1 : FStarC_Syntax_Syntax.fv) (f2 : FStarC_Syntax_Syntax.fv) :
  Prims.bool=
  let uu___ = FStarC_Util.physical_equality f1 f2 in
  if uu___
  then true
  else
    FStarC_Ident.lid_equals f1.FStarC_Syntax_Syntax.fv_name
      f2.FStarC_Syntax_Syntax.fv_name
and equal_universe (u1 : FStarC_Syntax_Syntax.universe)
  (u2 : FStarC_Syntax_Syntax.universe) : Prims.bool=
  let uu___ = FStarC_Util.physical_equality u1 u2 in
  if uu___
  then true
  else
    (let uu___2 =
       let uu___3 = FStarC_Syntax_Subst.compress_univ u1 in
       let uu___4 = FStarC_Syntax_Subst.compress_univ u2 in (uu___3, uu___4) in
     match uu___2 with
     | (FStarC_Syntax_Syntax.U_zero, FStarC_Syntax_Syntax.U_zero) -> true
     | (FStarC_Syntax_Syntax.U_succ u11, FStarC_Syntax_Syntax.U_succ u21) ->
         equal_universe u11 u21
     | (FStarC_Syntax_Syntax.U_max us1, FStarC_Syntax_Syntax.U_max us2) ->
         equal_list equal_universe us1 us2
     | (FStarC_Syntax_Syntax.U_bvar i1, FStarC_Syntax_Syntax.U_bvar i2) ->
         i1 = i2
     | (FStarC_Syntax_Syntax.U_name x1, FStarC_Syntax_Syntax.U_name x2) ->
         FStarC_Ident.ident_equals x1 x2
     | (FStarC_Syntax_Syntax.U_unif u11, FStarC_Syntax_Syntax.U_unif u21) ->
         FStarC_Syntax_Unionfind.univ_equiv u11 u21
     | (FStarC_Syntax_Syntax.U_unknown, FStarC_Syntax_Syntax.U_unknown) ->
         true
     | uu___3 -> false)
and equal_constant (c1 : FStarC_Syntax_Syntax.sconst)
  (c2 : FStarC_Syntax_Syntax.sconst) : Prims.bool=
  let uu___ = FStarC_Util.physical_equality c1 c2 in
  if uu___
  then true
  else
    (match (c1, c2) with
     | (FStarC_Const.Const_effect, FStarC_Const.Const_effect) -> true
     | (FStarC_Const.Const_unit, FStarC_Const.Const_unit) -> true
     | (FStarC_Const.Const_bool b1, FStarC_Const.Const_bool b2) -> b1 = b2
     | (FStarC_Const.Const_int (s1, o1), FStarC_Const.Const_int (s2, o2)) ->
         (s1 = s2) && (o1 = o2)
     | (FStarC_Const.Const_char c11, FStarC_Const.Const_char c21) ->
         c11 = c21
     | (FStarC_Const.Const_real s1, FStarC_Const.Const_real s2) -> s1 = s2
     | (FStarC_Const.Const_string (s1, uu___2), FStarC_Const.Const_string
        (s2, uu___3)) -> s1 = s2
     | (FStarC_Const.Const_range_of, FStarC_Const.Const_range_of) -> true
     | (FStarC_Const.Const_set_range_of, FStarC_Const.Const_set_range_of) ->
         true
     | (FStarC_Const.Const_range r1, FStarC_Const.Const_range r2) ->
         let uu___2 = FStarC_Range_Ops.compare r1 r2 in
         uu___2 = Prims.int_zero
     | (FStarC_Const.Const_reify uu___2, FStarC_Const.Const_reify uu___3) ->
         true
     | (FStarC_Const.Const_reflect l1, FStarC_Const.Const_reflect l2) ->
         FStarC_Ident.lid_equals l1 l2
     | uu___2 -> false)
and equal_arg
  (arg1 :
    (FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax *
      FStarC_Syntax_Syntax.arg_qualifier FStar_Pervasives_Native.option))
  (arg2 :
    (FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax *
      FStarC_Syntax_Syntax.arg_qualifier FStar_Pervasives_Native.option))
  : Prims.bool=
  let uu___ = FStarC_Util.physical_equality arg1 arg2 in
  if uu___
  then true
  else
    (let uu___2 = arg1 in
     match uu___2 with
     | (t1, a1) ->
         let uu___3 = arg2 in
         (match uu___3 with
          | (t2, a2) ->
              (equal_term t1 t2) && (equal_opt equal_arg_qualifier a1 a2)))
and equal_bqual
  (b1 : FStarC_Syntax_Syntax.binder_qualifier FStar_Pervasives_Native.option)
  (b2 : FStarC_Syntax_Syntax.binder_qualifier FStar_Pervasives_Native.option)
  : Prims.bool= equal_opt equal_binder_qualifier b1 b2
and equal_binder_qualifier (b1 : FStarC_Syntax_Syntax.binder_qualifier)
  (b2 : FStarC_Syntax_Syntax.binder_qualifier) : Prims.bool=
  match (b1, b2) with
  | (FStarC_Syntax_Syntax.Implicit b11, FStarC_Syntax_Syntax.Implicit b21) ->
      b11 = b21
  | (FStarC_Syntax_Syntax.Equality, FStarC_Syntax_Syntax.Equality) -> true
  | (FStarC_Syntax_Syntax.Meta t1, FStarC_Syntax_Syntax.Meta t2) ->
      equal_term t1 t2
  | uu___ -> false
and equal_branch
  (uu___ :
    (FStarC_Syntax_Syntax.pat' FStarC_Syntax_Syntax.withinfo_t *
      FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax
      FStar_Pervasives_Native.option * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax))
  (uu___1 :
    (FStarC_Syntax_Syntax.pat' FStarC_Syntax_Syntax.withinfo_t *
      FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax
      FStar_Pervasives_Native.option * FStarC_Syntax_Syntax.term'
      FStarC_Syntax_Syntax.syntax))
  : Prims.bool=
  match (uu___, uu___1) with
  | ((p1, w1, t1), (p2, w2, t2)) ->
      ((equal_pat p1 p2) && (equal_opt equal_term w1 w2)) &&
        (equal_term t1 t2)
and equal_pat
  (p1 : FStarC_Syntax_Syntax.pat' FStarC_Syntax_Syntax.withinfo_t)
  (p2 : FStarC_Syntax_Syntax.pat' FStarC_Syntax_Syntax.withinfo_t) :
  Prims.bool=
  let uu___ = FStarC_Util.physical_equality p1 p2 in
  if uu___
  then true
  else
    (match ((p1.FStarC_Syntax_Syntax.v), (p2.FStarC_Syntax_Syntax.v)) with
     | (FStarC_Syntax_Syntax.Pat_constant c1,
        FStarC_Syntax_Syntax.Pat_constant c2) -> equal_constant c1 c2
     | (FStarC_Syntax_Syntax.Pat_cons (fv1, us1, args1),
        FStarC_Syntax_Syntax.Pat_cons (fv2, us2, args2)) ->
         ((equal_fv fv1 fv2) &&
            (equal_opt (equal_list equal_universe) us1 us2))
           && (equal_list (equal_pair equal_pat equal_poly) args1 args2)
     | (FStarC_Syntax_Syntax.Pat_var bv1, FStarC_Syntax_Syntax.Pat_var bv2)
         -> equal_bv bv1 bv2
     | (FStarC_Syntax_Syntax.Pat_dot_term t1,
        FStarC_Syntax_Syntax.Pat_dot_term t2) -> equal_opt equal_term t1 t2
     | uu___2 -> false)
and equal_meta (m1 : FStarC_Syntax_Syntax.metadata)
  (m2 : FStarC_Syntax_Syntax.metadata) : Prims.bool=
  match (m1, m2) with
  | (FStarC_Syntax_Syntax.Meta_pattern (ts1, args1),
     FStarC_Syntax_Syntax.Meta_pattern (ts2, args2)) ->
      (equal_list equal_term ts1 ts2) &&
        (equal_list (equal_list equal_arg) args1 args2)
  | (FStarC_Syntax_Syntax.Meta_named l1, FStarC_Syntax_Syntax.Meta_named l2)
      -> FStarC_Ident.lid_equals l1 l2
  | (FStarC_Syntax_Syntax.Meta_labeled (s1, r1, uu___),
     FStarC_Syntax_Syntax.Meta_labeled (s2, r2, uu___1)) ->
      (s1 = s2) &&
        (let uu___2 = FStarC_Range_Ops.compare r1 r2 in
         uu___2 = Prims.int_zero)
  | (FStarC_Syntax_Syntax.Meta_desugared msi1,
     FStarC_Syntax_Syntax.Meta_desugared msi2) -> msi1 = msi2
  | (FStarC_Syntax_Syntax.Meta_monadic (m11, t1),
     FStarC_Syntax_Syntax.Meta_monadic (m21, t2)) ->
      (FStarC_Ident.lid_equals m11 m21) && (equal_term t1 t2)
  | (FStarC_Syntax_Syntax.Meta_monadic_lift (m11, n1, t1),
     FStarC_Syntax_Syntax.Meta_monadic_lift (m21, n2, t2)) ->
      ((FStarC_Ident.lid_equals m11 m21) && (FStarC_Ident.lid_equals n1 n2))
        && (equal_term t1 t2)
  | uu___ -> false
and equal_lazyinfo (l1 : FStarC_Syntax_Syntax.lazyinfo)
  (l2 : FStarC_Syntax_Syntax.lazyinfo) : Prims.bool=
  FStarC_Util.physical_equality l1.FStarC_Syntax_Syntax.blob
    l2.FStarC_Syntax_Syntax.blob
and equal_quoteinfo (q1 : FStarC_Syntax_Syntax.quoteinfo)
  (q2 : FStarC_Syntax_Syntax.quoteinfo) : Prims.bool=
  ((q1.FStarC_Syntax_Syntax.qkind = q2.FStarC_Syntax_Syntax.qkind) &&
     ((FStar_Pervasives_Native.fst q1.FStarC_Syntax_Syntax.antiquotations) =
        (FStar_Pervasives_Native.fst q2.FStarC_Syntax_Syntax.antiquotations)))
    &&
    (equal_list equal_term
       (FStar_Pervasives_Native.snd q1.FStarC_Syntax_Syntax.antiquotations)
       (FStar_Pervasives_Native.snd q2.FStarC_Syntax_Syntax.antiquotations))
and equal_rc (r1 : FStarC_Syntax_Syntax.residual_comp)
  (r2 : FStarC_Syntax_Syntax.residual_comp) : Prims.bool=
  ((FStarC_Ident.lid_equals r1.FStarC_Syntax_Syntax.residual_effect
      r2.FStarC_Syntax_Syntax.residual_effect)
     &&
     (equal_opt equal_term r1.FStarC_Syntax_Syntax.residual_typ
        r2.FStarC_Syntax_Syntax.residual_typ))
    &&
    (equal_list equal_flag r1.FStarC_Syntax_Syntax.residual_flags
       r2.FStarC_Syntax_Syntax.residual_flags)
and equal_flag (f1 : FStarC_Syntax_Syntax.cflag)
  (f2 : FStarC_Syntax_Syntax.cflag) : Prims.bool=
  match (f1, f2) with
  | (FStarC_Syntax_Syntax.DECREASES t1, FStarC_Syntax_Syntax.DECREASES t2) ->
      equal_decreases_order t1 t2
  | uu___ -> f1 = f2
and equal_decreases_order (d1 : FStarC_Syntax_Syntax.decreases_order)
  (d2 : FStarC_Syntax_Syntax.decreases_order) : Prims.bool=
  match (d1, d2) with
  | (FStarC_Syntax_Syntax.Decreases_lex ts1,
     FStarC_Syntax_Syntax.Decreases_lex ts2) -> equal_list equal_term ts1 ts2
  | (FStarC_Syntax_Syntax.Decreases_wf (t1, t1'),
     FStarC_Syntax_Syntax.Decreases_wf (t2, t2')) ->
      (equal_term t1 t2) && (equal_term t1' t2')
  | uu___ -> false
and equal_arg_qualifier (a1 : FStarC_Syntax_Syntax.arg_qualifier)
  (a2 : FStarC_Syntax_Syntax.arg_qualifier) : Prims.bool=
  (a1.FStarC_Syntax_Syntax.aqual_implicit =
     a2.FStarC_Syntax_Syntax.aqual_implicit)
    &&
    (equal_list equal_term a1.FStarC_Syntax_Syntax.aqual_attributes
       a2.FStarC_Syntax_Syntax.aqual_attributes)
and equal_lbname
  (l1 :
    (FStarC_Syntax_Syntax.bv, FStarC_Syntax_Syntax.fv)
      FStar_Pervasives.either)
  (l2 :
    (FStarC_Syntax_Syntax.bv, FStarC_Syntax_Syntax.fv)
      FStar_Pervasives.either)
  : Prims.bool=
  match (l1, l2) with
  | (FStar_Pervasives.Inl b1, FStar_Pervasives.Inl b2) ->
      FStarC_Ident.ident_equals b1.FStarC_Syntax_Syntax.ppname
        b2.FStarC_Syntax_Syntax.ppname
  | (FStar_Pervasives.Inr f1, FStar_Pervasives.Inr f2) ->
      FStarC_Ident.lid_equals f1.FStarC_Syntax_Syntax.fv_name
        f2.FStarC_Syntax_Syntax.fv_name
  | uu___ -> false
and equal_subst_elt (s1 : FStarC_Syntax_Syntax.subst_elt)
  (s2 : FStarC_Syntax_Syntax.subst_elt) : Prims.bool=
  match (s1, s2) with
  | (FStarC_Syntax_Syntax.DB (i1, bv1), FStarC_Syntax_Syntax.DB (i2, bv2)) ->
      (i1 = i2) && (equal_bv bv1 bv2)
  | (FStarC_Syntax_Syntax.NM (bv1, i1), FStarC_Syntax_Syntax.NM (bv2, i2)) ->
      (i1 = i2) && (equal_bv bv1 bv2)
  | (FStarC_Syntax_Syntax.NT (bv1, t1), FStarC_Syntax_Syntax.NT (bv2, t2)) ->
      (equal_bv bv1 bv2) && (equal_term t1 t2)
  | (FStarC_Syntax_Syntax.UN (i1, u1), FStarC_Syntax_Syntax.UN (i2, u2)) ->
      (i1 = i2) && (equal_universe u1 u2)
  | (FStarC_Syntax_Syntax.UD (un1, i1), FStarC_Syntax_Syntax.UD (un2, i2)) ->
      (i1 = i2) && (FStarC_Ident.ident_equals un1 un2)
  | (FStarC_Syntax_Syntax.DT (i1, t1), FStarC_Syntax_Syntax.DT (i2, t2)) ->
      (i1 = i2) && (equal_term t1 t2)
  | uu___ -> false
let hashable_term : FStarC_Syntax_Syntax.term FStarC_Class_Hashable.hashable=
  { FStarC_Class_Hashable.hash = ext_hash_term }
let hashable_lident : FStarC_Ident.lident FStarC_Class_Hashable.hashable=
  {
    FStarC_Class_Hashable.hash =
      (fun l ->
         let uu___ = FStarC_Ident.string_of_lid l in
         FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_string
           uu___)
  }
let hashable_ident : FStarC_Ident.ident FStarC_Class_Hashable.hashable=
  {
    FStarC_Class_Hashable.hash =
      (fun i ->
         let uu___ = FStarC_Ident.string_of_id i in
         FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_string
           uu___)
  }
let hashable_binding :
  FStarC_Syntax_Syntax.binding FStarC_Class_Hashable.hashable=
  {
    FStarC_Class_Hashable.hash =
      (fun uu___ ->
         match uu___ with
         | FStarC_Syntax_Syntax.Binding_var bv ->
             FStarC_Class_Hashable.hash hashable_term
               bv.FStarC_Syntax_Syntax.sort
         | FStarC_Syntax_Syntax.Binding_lid (l, (us, t)) ->
             let uu___1 =
               let uu___2 = FStarC_Class_Hashable.hash hashable_lident l in
               let uu___3 =
                 FStarC_Class_Hashable.hash
                   (FStarC_Class_Hashable.hashable_list hashable_ident) us in
               FStarC_Hash.mix uu___2 uu___3 in
             let uu___2 = FStarC_Class_Hashable.hash hashable_term t in
             FStarC_Hash.mix uu___1 uu___2
         | FStarC_Syntax_Syntax.Binding_univ u ->
             FStarC_Class_Hashable.hash hashable_ident u)
  }
let hashable_bv : FStarC_Syntax_Syntax.bv FStarC_Class_Hashable.hashable=
  {
    FStarC_Class_Hashable.hash =
      (fun b ->
         FStarC_Class_Hashable.hash hashable_term b.FStarC_Syntax_Syntax.sort)
  }
let hashable_fv : FStarC_Syntax_Syntax.fv FStarC_Class_Hashable.hashable=
  {
    FStarC_Class_Hashable.hash =
      (fun f ->
         FStarC_Class_Hashable.hash hashable_lident
           f.FStarC_Syntax_Syntax.fv_name)
  }
let hashable_binder :
  FStarC_Syntax_Syntax.binder FStarC_Class_Hashable.hashable=
  {
    FStarC_Class_Hashable.hash =
      (fun b ->
         FStarC_Class_Hashable.hash hashable_bv
           b.FStarC_Syntax_Syntax.binder_bv)
  }
let hashable_letbinding :
  FStarC_Syntax_Syntax.letbinding FStarC_Class_Hashable.hashable=
  {
    FStarC_Class_Hashable.hash =
      (fun lb ->
         let uu___ =
           let uu___1 =
             FStarC_Class_Hashable.hash
               (FStarC_Class_Hashable.hashable_either hashable_bv hashable_fv)
               lb.FStarC_Syntax_Syntax.lbname in
           let uu___2 =
             FStarC_Class_Hashable.hash hashable_term
               lb.FStarC_Syntax_Syntax.lbtyp in
           FStarC_Hash.mix uu___1 uu___2 in
         let uu___1 =
           FStarC_Class_Hashable.hash hashable_term
             lb.FStarC_Syntax_Syntax.lbdef in
         FStarC_Hash.mix uu___ uu___1)
  }
let hashable_pragma :
  FStarC_Syntax_Syntax.pragma FStarC_Class_Hashable.hashable=
  {
    FStarC_Class_Hashable.hash =
      (fun uu___ ->
         match uu___ with
         | FStarC_Syntax_Syntax.ShowOptions ->
             FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
               Prims.int_one
         | FStarC_Syntax_Syntax.SetOptions s ->
             let uu___1 =
               FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
                 (Prims.of_int (2)) in
             let uu___2 =
               FStarC_Class_Hashable.hash
                 FStarC_Class_Hashable.hashable_string s in
             FStarC_Hash.mix uu___1 uu___2
         | FStarC_Syntax_Syntax.ResetOptions s ->
             let uu___1 =
               FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
                 (Prims.of_int (3)) in
             let uu___2 =
               FStarC_Class_Hashable.hash
                 (FStarC_Class_Hashable.hashable_option
                    FStarC_Class_Hashable.hashable_string) s in
             FStarC_Hash.mix uu___1 uu___2
         | FStarC_Syntax_Syntax.PushOptions s ->
             let uu___1 =
               FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
                 (Prims.of_int (4)) in
             let uu___2 =
               FStarC_Class_Hashable.hash
                 (FStarC_Class_Hashable.hashable_option
                    FStarC_Class_Hashable.hashable_string) s in
             FStarC_Hash.mix uu___1 uu___2
         | FStarC_Syntax_Syntax.PopOptions ->
             FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
               (Prims.of_int (5))
         | FStarC_Syntax_Syntax.RestartSolver ->
             FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
               (Prims.of_int (6))
         | FStarC_Syntax_Syntax.PrintEffectsGraph ->
             FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
               (Prims.of_int (7))
         | FStarC_Syntax_Syntax.Check t ->
             let uu___1 =
               FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
                 (Prims.of_int (8)) in
             let uu___2 = FStarC_Class_Hashable.hash hashable_term t in
             FStarC_Hash.mix uu___1 uu___2)
  }
let rec hash_sigelt (se : FStarC_Syntax_Syntax.sigelt) :
  FStarC_Hash.hash_code= hash_sigelt' se.FStarC_Syntax_Syntax.sigel
and hash_sigelt' (se : FStarC_Syntax_Syntax.sigelt') : FStarC_Hash.hash_code=
  match se with
  | FStarC_Syntax_Syntax.Sig_inductive_typ
      { FStarC_Syntax_Syntax.lid = lid; FStarC_Syntax_Syntax.us = us;
        FStarC_Syntax_Syntax.params = params;
        FStarC_Syntax_Syntax.num_uniform_params = num_uniform_params;
        FStarC_Syntax_Syntax.t = t; FStarC_Syntax_Syntax.mutuals = mutuals;
        FStarC_Syntax_Syntax.ds = ds;
        FStarC_Syntax_Syntax.injective_type_params = injective_type_params;_}
      ->
      let uu___ =
        let uu___1 =
          let uu___2 =
            let uu___3 =
              let uu___4 =
                let uu___5 =
                  let uu___6 =
                    let uu___7 =
                      FStarC_Class_Hashable.hash
                        FStarC_Class_Hashable.hashable_int Prims.int_zero in
                    let uu___8 =
                      FStarC_Class_Hashable.hash hashable_lident lid in
                    FStarC_Hash.mix uu___7 uu___8 in
                  let uu___7 =
                    FStarC_Class_Hashable.hash
                      (FStarC_Class_Hashable.hashable_list hashable_ident) us in
                  FStarC_Hash.mix uu___6 uu___7 in
                let uu___6 =
                  FStarC_Class_Hashable.hash
                    (FStarC_Class_Hashable.hashable_list hashable_binder)
                    params in
                FStarC_Hash.mix uu___5 uu___6 in
              let uu___5 =
                FStarC_Class_Hashable.hash
                  (FStarC_Class_Hashable.hashable_option
                     FStarC_Class_Hashable.hashable_int) num_uniform_params in
              FStarC_Hash.mix uu___4 uu___5 in
            let uu___4 = FStarC_Class_Hashable.hash hashable_term t in
            FStarC_Hash.mix uu___3 uu___4 in
          let uu___3 =
            FStarC_Class_Hashable.hash
              (FStarC_Class_Hashable.hashable_list hashable_lident) mutuals in
          FStarC_Hash.mix uu___2 uu___3 in
        let uu___2 =
          FStarC_Class_Hashable.hash
            (FStarC_Class_Hashable.hashable_list hashable_lident) ds in
        FStarC_Hash.mix uu___1 uu___2 in
      let uu___1 =
        FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_bool
          injective_type_params in
      FStarC_Hash.mix uu___ uu___1
  | FStarC_Syntax_Syntax.Sig_bundle
      { FStarC_Syntax_Syntax.ses = ses; FStarC_Syntax_Syntax.lids = lids;_}
      ->
      let uu___ =
        let uu___1 =
          FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
            Prims.int_one in
        let uu___2 =
          (FStarC_Class_Hashable.hashable_list
             { FStarC_Class_Hashable.hash = hash_sigelt }).FStarC_Class_Hashable.hash
            ses in
        FStarC_Hash.mix uu___1 uu___2 in
      let uu___1 =
        FStarC_Class_Hashable.hash
          (FStarC_Class_Hashable.hashable_list hashable_lident) lids in
      FStarC_Hash.mix uu___ uu___1
  | FStarC_Syntax_Syntax.Sig_datacon
      { FStarC_Syntax_Syntax.lid1 = lid; FStarC_Syntax_Syntax.us1 = us;
        FStarC_Syntax_Syntax.t1 = t; FStarC_Syntax_Syntax.ty_lid = ty_lid;
        FStarC_Syntax_Syntax.num_ty_params = num_ty_params;
        FStarC_Syntax_Syntax.mutuals1 = mutuals;
        FStarC_Syntax_Syntax.injective_type_params1 = injective_type_params;
        FStarC_Syntax_Syntax.proj_disc_lids = uu___;_}
      ->
      let uu___1 =
        let uu___2 =
          let uu___3 =
            let uu___4 =
              let uu___5 =
                let uu___6 =
                  let uu___7 =
                    FStarC_Class_Hashable.hash
                      FStarC_Class_Hashable.hashable_int (Prims.of_int (2)) in
                  let uu___8 = FStarC_Class_Hashable.hash hashable_lident lid in
                  FStarC_Hash.mix uu___7 uu___8 in
                let uu___7 =
                  FStarC_Class_Hashable.hash
                    (FStarC_Class_Hashable.hashable_list hashable_ident) us in
                FStarC_Hash.mix uu___6 uu___7 in
              let uu___6 = FStarC_Class_Hashable.hash hashable_term t in
              FStarC_Hash.mix uu___5 uu___6 in
            let uu___5 = FStarC_Class_Hashable.hash hashable_lident ty_lid in
            FStarC_Hash.mix uu___4 uu___5 in
          let uu___4 =
            FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
              num_ty_params in
          FStarC_Hash.mix uu___3 uu___4 in
        let uu___3 =
          FStarC_Class_Hashable.hash
            (FStarC_Class_Hashable.hashable_list hashable_lident) mutuals in
        FStarC_Hash.mix uu___2 uu___3 in
      let uu___2 =
        FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_bool
          injective_type_params in
      FStarC_Hash.mix uu___1 uu___2
  | FStarC_Syntax_Syntax.Sig_declare_typ
      { FStarC_Syntax_Syntax.lid2 = lid; FStarC_Syntax_Syntax.us2 = us;
        FStarC_Syntax_Syntax.t2 = t;_}
      ->
      let uu___ =
        let uu___1 =
          let uu___2 =
            FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
              (Prims.of_int (3)) in
          let uu___3 = FStarC_Class_Hashable.hash hashable_lident lid in
          FStarC_Hash.mix uu___2 uu___3 in
        let uu___2 =
          FStarC_Class_Hashable.hash
            (FStarC_Class_Hashable.hashable_list hashable_ident) us in
        FStarC_Hash.mix uu___1 uu___2 in
      let uu___1 = FStarC_Class_Hashable.hash hashable_term t in
      FStarC_Hash.mix uu___ uu___1
  | FStarC_Syntax_Syntax.Sig_let
      { FStarC_Syntax_Syntax.lbs1 = lbs; FStarC_Syntax_Syntax.lids1 = lids;_}
      ->
      let uu___ =
        let uu___1 =
          FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
            (Prims.of_int (4)) in
        let uu___2 =
          FStarC_Class_Hashable.hash
            (FStarC_Class_Hashable.hashable_tuple2
               FStarC_Class_Hashable.hashable_bool
               (FStarC_Class_Hashable.hashable_list hashable_letbinding)) lbs in
        FStarC_Hash.mix uu___1 uu___2 in
      let uu___1 =
        FStarC_Class_Hashable.hash
          (FStarC_Class_Hashable.hashable_list hashable_lident) lids in
      FStarC_Hash.mix uu___ uu___1
  | FStarC_Syntax_Syntax.Sig_assume
      { FStarC_Syntax_Syntax.lid3 = lid; FStarC_Syntax_Syntax.us3 = us;
        FStarC_Syntax_Syntax.phi1 = phi;_}
      ->
      let uu___ =
        let uu___1 =
          let uu___2 =
            FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
              (Prims.of_int (5)) in
          let uu___3 = FStarC_Class_Hashable.hash hashable_lident lid in
          FStarC_Hash.mix uu___2 uu___3 in
        let uu___2 =
          FStarC_Class_Hashable.hash
            (FStarC_Class_Hashable.hashable_list hashable_ident) us in
        FStarC_Hash.mix uu___1 uu___2 in
      let uu___1 = FStarC_Class_Hashable.hash hashable_term phi in
      FStarC_Hash.mix uu___ uu___1
  | FStarC_Syntax_Syntax.Sig_pragma p ->
      let uu___ =
        FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
          (Prims.of_int (6)) in
      let uu___1 = FStarC_Class_Hashable.hash hashable_pragma p in
      FStarC_Hash.mix uu___ uu___1
  | uu___ ->
      FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
        Prims.int_zero
let hashable_sigelt :
  FStarC_Syntax_Syntax.sigelt FStarC_Class_Hashable.hashable=
  { FStarC_Class_Hashable.hash = hash_sigelt }
let deq_term : FStarC_Syntax_Syntax.term FStarC_Class_Deq.deq=
  { FStarC_Class_Deq.op_Equals_Question = equal_term }
type 'a term_map = (FStarC_Syntax_Syntax.term, 'a) FStarC_HashMap.hashmap
let term_map_empty (uu___ : unit) : 'a term_map= FStarC_HashMap.empty ()
let term_map_add (t : FStarC_Syntax_Syntax.term) (v : 'a) (m : 'a term_map) :
  'a term_map= FStarC_HashMap.add deq_term hashable_term t v m
let term_map_lookup (t : FStarC_Syntax_Syntax.term) (m : 'a term_map) :
  'a FStar_Pervasives_Native.option=
  FStarC_HashMap.lookup deq_term hashable_term t m
let term_map_mem (t : FStarC_Syntax_Syntax.term) (m : 'a term_map) :
  Prims.bool= FStarC_HashMap.mem deq_term hashable_term t m
let term_map_fold (f : FStarC_Syntax_Syntax.term -> 'a -> 'b -> 'b)
  (m : 'a term_map) (i : 'b) : 'b=
  FStarC_HashMap.fold deq_term hashable_term f m i
