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) -> g t1 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___ = f h in uu___ should_memo1)
let of_int (i : Prims.int) : FStarC_Hash.hash_code mm=
  ret (FStarC_Hash.of_int i)
let of_string (s : Prims.string) : FStarC_Hash.hash_code mm=
  ret (FStarC_Hash.of_string s)
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) -> ((FStarC_Hash.mix x y), (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 ->
      ret (FStarC_Hash.of_int (Prims.of_int 1237))
  | FStar_Pervasives_Native.Some o1 ->
      let uu___ = h o1 in
      mix (ret (FStarC_Hash.of_int (Prims.of_int 1249))) uu___
let hash_doc (d : FStar_Pprint.document) : FStarC_Hash.hash_code mm=
  of_string
    (FStarC_Pprint.pretty_string (FStarC_Util.float_of_string "1.0")
       (Prims.of_int 80) d)
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 ->
      mix (of_int (Prims.of_int 3)) (of_int bv.FStarC_Syntax_Syntax.index)
  | FStarC_Syntax_Syntax.Tm_name bv ->
      mix (of_int (Prims.of_int 5)) (of_int bv.FStarC_Syntax_Syntax.index)
  | FStarC_Syntax_Syntax.Tm_fvar fv ->
      let uu___1 = hash_fv fv in mix (of_int (Prims.of_int 7)) uu___1
  | FStarC_Syntax_Syntax.Tm_uinst (t1, us) ->
      let uu___1 =
        let uu___2 = hash_term t1 in
        let uu___3 = hash_list hash_universe us in mix uu___2 uu___3 in
      mix (of_int (Prims.of_int 11)) uu___1
  | FStarC_Syntax_Syntax.Tm_constant sc ->
      let uu___1 = hash_constant sc in mix (of_int (Prims.of_int 13)) uu___1
  | FStarC_Syntax_Syntax.Tm_type u ->
      let uu___1 = hash_universe u in mix (of_int (Prims.of_int 17)) uu___1
  | FStarC_Syntax_Syntax.Tm_abs
      { FStarC_Syntax_Syntax.bs = bs; FStarC_Syntax_Syntax.body = t1;
        FStarC_Syntax_Syntax.rc_opt = rcopt;_}
      ->
      let uu___1 =
        let uu___2 = hash_list hash_binder bs in
        let uu___3 =
          let uu___4 = hash_term t1 in
          let uu___5 = hash_option hash_rc rcopt in mix uu___4 uu___5 in
        mix uu___2 uu___3 in
      mix (of_int (Prims.of_int 19)) uu___1
  | FStarC_Syntax_Syntax.Tm_arrow
      { FStarC_Syntax_Syntax.bs1 = bs; FStarC_Syntax_Syntax.comp = c;_} ->
      let uu___1 =
        let uu___2 = hash_list hash_binder bs in
        let uu___3 = hash_comp c in mix uu___2 uu___3 in
      mix (of_int (Prims.of_int 23)) uu___1
  | FStarC_Syntax_Syntax.Tm_refine
      { FStarC_Syntax_Syntax.b = b; FStarC_Syntax_Syntax.phi = t1;_} ->
      let uu___1 =
        let uu___2 = hash_bv b in
        let uu___3 = hash_term t1 in mix uu___2 uu___3 in
      mix (of_int (Prims.of_int 29)) uu___1
  | 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 =
        let uu___2 = hash_option hash_match_returns asc_opt in
        let uu___3 =
          let uu___4 =
            let uu___5 = hash_term t1 in
            let uu___6 = hash_list hash_branch branches in mix uu___5 uu___6 in
          let uu___5 = hash_option hash_rc rcopt in mix uu___4 uu___5 in
        mix uu___2 uu___3 in
      mix (of_int (Prims.of_int 37)) uu___1
  | FStarC_Syntax_Syntax.Tm_ascribed
      { FStarC_Syntax_Syntax.tm = t1; FStarC_Syntax_Syntax.asc = a;
        FStarC_Syntax_Syntax.eff_opt = lopt;_}
      ->
      let uu___1 =
        let uu___2 = hash_term t1 in
        let uu___3 =
          let uu___4 = hash_ascription a in
          let uu___5 = hash_option hash_lid lopt in mix uu___4 uu___5 in
        mix uu___2 uu___3 in
      mix (of_int (Prims.of_int 43)) uu___1
  | FStarC_Syntax_Syntax.Tm_let
      { FStarC_Syntax_Syntax.lbs = (false, lb::[]);
        FStarC_Syntax_Syntax.body1 = t1;_}
      ->
      let uu___1 =
        let uu___2 = hash_lb lb in
        let uu___3 = hash_term t1 in mix uu___2 uu___3 in
      mix (of_int (Prims.of_int 47)) uu___1
  | FStarC_Syntax_Syntax.Tm_let
      { FStarC_Syntax_Syntax.lbs = (uu___1, lbs);
        FStarC_Syntax_Syntax.body1 = t1;_}
      ->
      let uu___2 =
        let uu___3 = hash_list hash_lb lbs in
        let uu___4 = hash_term t1 in mix uu___3 uu___4 in
      mix (of_int (Prims.of_int 51)) uu___2
  | FStarC_Syntax_Syntax.Tm_uvar uv ->
      let uu___1 = hash_uvar uv in mix (of_int (Prims.of_int 53)) uu___1
  | FStarC_Syntax_Syntax.Tm_meta
      { FStarC_Syntax_Syntax.tm2 = t1; FStarC_Syntax_Syntax.meta = m;_} ->
      let uu___1 =
        let uu___2 = hash_term t1 in
        let uu___3 = hash_meta m in mix uu___2 uu___3 in
      mix (of_int (Prims.of_int 61)) uu___1
  | FStarC_Syntax_Syntax.Tm_lazy li ->
      let uu___1 = hash_lazyinfo li in mix (of_int (Prims.of_int 67)) uu___1
  | FStarC_Syntax_Syntax.Tm_quoted (t1, qi) ->
      let uu___1 =
        let uu___2 = hash_term t1 in
        let uu___3 = hash_quoteinfo qi in mix uu___2 uu___3 in
      mix (of_int (Prims.of_int 71)) uu___1
  | FStarC_Syntax_Syntax.Tm_unknown -> of_int (Prims.of_int 73)
  | FStarC_Syntax_Syntax.Tm_delayed uu___1 ->
      FStarC_Effect.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 = let uu___2 = hash_term t in [uu___2] in
        (of_int (Prims.of_int 811)) :: uu___1 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.GTotal t ->
      let uu___ =
        let uu___1 = let uu___2 = hash_term t in [uu___2] in
        (of_int (Prims.of_int 821)) :: uu___1 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Comp ct ->
      let uu___ =
        let uu___1 =
          let uu___2 =
            hash_list hash_universe ct.FStarC_Syntax_Syntax.comp_univs in
          let uu___3 =
            let uu___4 = hash_lid ct.FStarC_Syntax_Syntax.effect_name in
            let uu___5 =
              let uu___6 = hash_term ct.FStarC_Syntax_Syntax.result_typ in
              let uu___7 =
                let uu___8 =
                  hash_list hash_arg ct.FStarC_Syntax_Syntax.effect_args in
                let uu___9 =
                  let uu___10 =
                    hash_list hash_flag ct.FStarC_Syntax_Syntax.flags in
                  [uu___10] in
                uu___8 :: uu___9 in
              uu___6 :: uu___7 in
            uu___4 :: uu___5 in
          uu___2 :: uu___3 in
        (of_int (Prims.of_int 823)) :: uu___1 in
      mix_list_lit uu___
and hash_lb (lb : FStarC_Syntax_Syntax.letbinding) :
  FStarC_Hash.hash_code mm=
  let uu___ =
    let uu___1 =
      let uu___2 = hash_lbname lb.FStarC_Syntax_Syntax.lbname in
      let uu___3 =
        let uu___4 = hash_list hash_ident lb.FStarC_Syntax_Syntax.lbunivs in
        let uu___5 =
          let uu___6 = hash_term lb.FStarC_Syntax_Syntax.lbtyp in
          let uu___7 =
            let uu___8 = hash_lid lb.FStarC_Syntax_Syntax.lbeff in
            let uu___9 =
              let uu___10 = hash_term lb.FStarC_Syntax_Syntax.lbdef in
              let uu___11 =
                let uu___12 =
                  hash_list hash_term lb.FStarC_Syntax_Syntax.lbattrs in
                [uu___12] in
              uu___10 :: uu___11 in
            uu___8 :: uu___9 in
          uu___6 :: uu___7 in
        uu___4 :: uu___5 in
      uu___2 :: uu___3 in
    (of_int (Prims.of_int 79)) :: uu___1 in
  mix_list_lit uu___
and hash_match_returns
  (x :
    (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=
  let uu___ = x in
  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 =
          let uu___3 = hash_pat p in
          let uu___4 =
            let uu___5 = hash_option hash_term topt in
            let uu___6 = let uu___7 = hash_term t in [uu___7] in uu___5 ::
              uu___6 in
          uu___3 :: uu___4 in
        (of_int (Prims.of_int 83)) :: uu___2 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___ = hash_constant c in mix (of_int (Prims.of_int 89)) uu___
  | FStarC_Syntax_Syntax.Pat_cons (fv, us, args) ->
      let uu___ =
        let uu___1 =
          let uu___2 = hash_fv fv in
          let uu___3 =
            let uu___4 = hash_option (hash_list hash_universe) us in
            let uu___5 =
              let uu___6 = hash_list (hash_pair hash_pat hash_bool) args in
              [uu___6] in
            uu___4 :: uu___5 in
          uu___2 :: uu___3 in
        (of_int (Prims.of_int 97)) :: uu___1 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Pat_var bv ->
      let uu___ = hash_bv bv in mix (of_int (Prims.of_int 101)) uu___
  | FStarC_Syntax_Syntax.Pat_dot_term t ->
      let uu___ =
        let uu___1 = let uu___2 = hash_option hash_term t in [uu___2] in
        (of_int (Prims.of_int 107)) :: uu___1 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=
  of_string (FStarC_Ident.string_of_lid fv.FStarC_Syntax_Syntax.fv_name)
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 (u : FStarC_Syntax_Syntax.universe) :
  FStarC_Hash.hash_code mm=
  match u with
  | FStarC_Syntax_Syntax.U_zero -> of_int (Prims.of_int 179)
  | FStarC_Syntax_Syntax.U_succ u1 ->
      let uu___ = hash_universe u1 in mix (of_int (Prims.of_int 181)) uu___
  | FStarC_Syntax_Syntax.U_max us ->
      let uu___ = hash_list hash_universe us in
      mix (of_int (Prims.of_int 191)) uu___
  | FStarC_Syntax_Syntax.U_bvar i ->
      mix (of_int (Prims.of_int 193)) (of_int i)
  | FStarC_Syntax_Syntax.U_name i ->
      let uu___ = hash_ident i in mix (of_int (Prims.of_int 197)) uu___
  | FStarC_Syntax_Syntax.U_unif uv ->
      let uu___ = hash_universe_uvar uv in
      mix (of_int (Prims.of_int 199)) uu___
  | FStarC_Syntax_Syntax.U_unknown -> of_int (Prims.of_int 211)
and hash_arg
  (x :
    (FStarC_Syntax_Syntax.term' FStarC_Syntax_Syntax.syntax *
      FStarC_Syntax_Syntax.arg_qualifier FStar_Pervasives_Native.option))
  : FStarC_Hash.hash_code mm=
  let uu___ = x in
  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 (bq : FStarC_Syntax_Syntax.binder_qualifier) :
  FStarC_Hash.hash_code mm=
  match bq 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___ = hash_term t in mix (of_int (Prims.of_int 431)) uu___
  | FStarC_Syntax_Syntax.Equality -> of_int (Prims.of_int 433)
and hash_uvar
  (x :
    (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=
  let uu___ = x in
  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
  (x :
    ((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=
  let uu___ = x in
  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 (c : FStarC_Syntax_Syntax.sconst) :
  FStarC_Hash.hash_code mm=
  match c 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___ =
        let uu___1 = hash_option hash_sw o in mix (of_string s) uu___1 in
      mix (of_int (Prims.of_int 313)) uu___
  | FStarC_Const.Const_char c1 ->
      mix (of_int (Prims.of_int 317)) (of_int (FStar_Char.int_of_char c1))
  | FStarC_Const.Const_real s ->
      mix (of_int (Prims.of_int 337)) (of_string s)
  | FStarC_Const.Const_string (s, uu___) ->
      mix (of_int (Prims.of_int 349)) (of_string s)
  | 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___ =
        let uu___1 = FStarC_Range_Ops.string_of_range r in of_string uu___1 in
      mix (of_int (Prims.of_int 367)) uu___
  | FStarC_Const.Const_reify uu___ -> of_int (Prims.of_int 367)
  | FStarC_Const.Const_reflect l ->
      let uu___ = hash_lid l in mix (of_int (Prims.of_int 373)) uu___
and hash_sw (x : (FStarC_Const.signedness * FStarC_Const.width)) :
  FStarC_Hash.hash_code mm=
  let uu___ = x in
  match uu___ with
  | (s, w) ->
      mix
        (match s with
         | FStarC_Const.Unsigned -> of_int (Prims.of_int 547)
         | FStarC_Const.Signed -> of_int (Prims.of_int 557))
        (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))
and hash_ident (i : FStarC_Syntax_Syntax.univ_name) :
  FStarC_Hash.hash_code mm= of_string (FStarC_Ident.string_of_id i)
and hash_lid (l : FStarC_Ident.lident) : FStarC_Hash.hash_code mm=
  of_string (FStarC_Ident.string_of_lid l)
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 (f : FStarC_Syntax_Syntax.cflag) : FStarC_Hash.hash_code mm=
  match f 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.DECREASES (FStarC_Syntax_Syntax.Decreases_lex ts) ->
      let uu___ = hash_list hash_term ts in
      mix (of_int (Prims.of_int 1013)) uu___
  | FStarC_Syntax_Syntax.DECREASES (FStarC_Syntax_Syntax.Decreases_wf
      (t0, t1)) ->
      let uu___ = hash_list hash_term [t0; t1] in
      mix (of_int (Prims.of_int 2341)) uu___
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 =
          let uu___2 = hash_list hash_term ts in
          let uu___3 =
            let uu___4 = hash_list (hash_list hash_arg) args in [uu___4] in
          uu___2 :: uu___3 in
        (of_int (Prims.of_int 1019)) :: uu___1 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Meta_named l ->
      let uu___ =
        let uu___1 = let uu___2 = hash_lid l in [uu___2] in
        (of_int (Prims.of_int 1021)) :: uu___1 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Meta_labeled (s, r, uu___) ->
      let uu___1 =
        let uu___2 =
          let uu___3 = hash_doc_list s in
          let uu___4 =
            let uu___5 =
              let uu___6 = FStarC_Range_Ops.string_of_range r in
              of_string uu___6 in
            [uu___5] in
          uu___3 :: uu___4 in
        (of_int (Prims.of_int 1031)) :: uu___2 in
      mix_list_lit uu___1
  | FStarC_Syntax_Syntax.Meta_desugared msi ->
      let uu___ =
        let uu___1 = let uu___2 = hash_meta_source_info msi in [uu___2] in
        (of_int (Prims.of_int 1033)) :: uu___1 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Meta_monadic (m1, t) ->
      let uu___ =
        let uu___1 =
          let uu___2 = hash_lid m1 in
          let uu___3 = let uu___4 = hash_term t in [uu___4] in uu___2 ::
            uu___3 in
        (of_int (Prims.of_int 1039)) :: uu___1 in
      mix_list_lit uu___
  | FStarC_Syntax_Syntax.Meta_monadic_lift (m0, m1, t) ->
      let uu___ =
        let uu___1 =
          let uu___2 = hash_lid m0 in
          let uu___3 =
            let uu___4 = hash_lid m1 in
            let uu___5 = let uu___6 = hash_term t in [uu___6] in uu___4 ::
              uu___5 in
          uu___2 :: uu___3 in
        (of_int (Prims.of_int 1069)) :: uu___1 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___ = hash_sw sw in mix (of_int (Prims.of_int 1069)) uu___
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 :
  'a .
    ('a -> 'a -> Prims.bool) -> 'a Prims.list -> 'a Prims.list -> Prims.bool
  =
  fun f l1 l2 ->
    match (l1, l2) with
    | ([], []) -> true
    | (h1::t1, h2::t2) ->
        let uu___ = f h1 h2 in if uu___ then equal_list f t1 t2 else false
    | uu___ -> false
let equal_opt (f : 'a -> 'a -> Prims.bool)
  (o1 : 'a FStar_Pervasives_Native.option)
  (o2 : 'a FStar_Pervasives_Native.option) : Prims.bool=
  match (o1, o2) with
  | (FStar_Pervasives_Native.None, FStar_Pervasives_Native.None) -> true
  | (FStar_Pervasives_Native.Some a1, FStar_Pervasives_Native.Some b) ->
      f a1 b
  | uu___ -> false
let equal_pair (f : 'a -> 'a -> Prims.bool) (g : 'b -> 'b -> Prims.bool)
  (x1 : ('a * 'b)) (x2 : ('a * 'b)) : Prims.bool=
  let uu___ =
    f (FStar_Pervasives_Native.fst x1) (FStar_Pervasives_Native.fst x2) in
  if uu___
  then g (FStar_Pervasives_Native.snd x1) (FStar_Pervasives_Native.snd x2)
  else false
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 r = hash_term t in
  let uu___ = r true in match uu___ with | (h, uu___1) -> h
let ext_hash_term_no_memo (t : FStarC_Syntax_Syntax.term) :
  FStarC_Hash.hash_code=
  let r = hash_term t in
  let uu___ = r false in match uu___ with | (h, uu___1) -> h
let rec equal_term (t1 : FStarC_Syntax_Syntax.term)
  (t2 : FStarC_Syntax_Syntax.term) : Prims.bool=
  if FStarC_Util.physical_equality t1 t2
  then true
  else
    if
      FStarC_Util.physical_equality t1.FStarC_Syntax_Syntax.n
        t2.FStarC_Syntax_Syntax.n
    then true
    else
      (let uu___ =
         let uu___1 = ext_hash_term t1 in
         let uu___2 = ext_hash_term t2 in uu___1 <> uu___2 in
       if uu___
       then false
       else
         (let uu___1 =
            let uu___2 =
              let uu___3 = FStarC_Syntax_Subst.compress t1 in
              uu___3.FStarC_Syntax_Syntax.n in
            let uu___3 =
              let uu___4 = FStarC_Syntax_Subst.compress t2 in
              uu___4.FStarC_Syntax_Syntax.n in
            (uu___2, uu___3) in
          match uu___1 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)) ->
              let uu___2 = equal_term t11 t21 in
              if uu___2 then equal_list equal_universe u1 u2 else false
          | (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;_})
              ->
              let uu___2 =
                let uu___3 = equal_list equal_binder bs1 bs2 in
                if uu___3 then equal_term t11 t21 else false in
              if uu___2 then equal_opt equal_rc rc1 rc2 else false
          | (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;_})
              ->
              let uu___2 = equal_list equal_binder bs1 bs2 in
              if uu___2 then equal_comp c1 c2 else false
          | (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;_})
              ->
              let uu___2 = equal_bv b1 b2 in
              if uu___2 then equal_term t11 t21 else false
          | (FStarC_Syntax_Syntax.Tm_app uu___2, FStarC_Syntax_Syntax.Tm_app
             uu___3) ->
              let uu___4 = FStarC_Syntax_Util.head_and_args_full t1 in
              (match uu___4 with
               | (hd1, args1) ->
                   let uu___5 = FStarC_Syntax_Util.head_and_args_full t2 in
                   (match uu___5 with
                    | (hd2, args2) ->
                        let uu___6 = equal_term hd1 hd2 in
                        if uu___6
                        then equal_list equal_arg args1 args2
                        else false))
          | (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;_})
              ->
              let uu___2 =
                let uu___3 =
                  let uu___4 = equal_term t11 t21 in
                  if uu___4
                  then equal_opt equal_match_returns asc_opt1 asc_opt2
                  else false in
                if uu___3 then equal_list equal_branch bs1 bs2 else false in
              if uu___2 then equal_opt equal_rc ropt1 ropt2 else false
          | (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;_})
              ->
              let uu___2 =
                let uu___3 = equal_term t11 t21 in
                if uu___3 then equal_ascription a1 a2 else false in
              if uu___2
              then equal_opt FStarC_Ident.lid_equals l1 l2
              else false
          | (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;_})
              ->
              let uu___2 =
                if r1 = r2
                then equal_list equal_letbinding lbs1 lbs2
                else false in
              if uu___2 then equal_term t11 t21 else false
          | (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;_})
              ->
              let uu___2 = equal_term t11 t21 in
              if uu___2 then equal_meta m1 m2 else false
          | (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)) ->
              let uu___2 = equal_term t11 t21 in
              if uu___2 then equal_quoteinfo q1 q2 else false
          | (FStarC_Syntax_Syntax.Tm_unknown,
             FStarC_Syntax_Syntax.Tm_unknown) -> true
          | uu___2 -> false))
and equal_comp (c1 : FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax)
  (c2 : FStarC_Syntax_Syntax.comp' FStarC_Syntax_Syntax.syntax) : Prims.bool=
  if FStarC_Util.physical_equality c1 c2
  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) ->
         let uu___ =
           let uu___1 =
             let uu___2 =
               if
                 FStarC_Ident.lid_equals ct1.FStarC_Syntax_Syntax.effect_name
                   ct2.FStarC_Syntax_Syntax.effect_name
               then
                 equal_list equal_universe
                   ct1.FStarC_Syntax_Syntax.comp_univs
                   ct2.FStarC_Syntax_Syntax.comp_univs
               else false in
             if uu___2
             then
               equal_term ct1.FStarC_Syntax_Syntax.result_typ
                 ct2.FStarC_Syntax_Syntax.result_typ
             else false in
           if uu___1
           then
             equal_list equal_arg ct1.FStarC_Syntax_Syntax.effect_args
               ct2.FStarC_Syntax_Syntax.effect_args
           else false in
         if uu___
         then
           equal_list equal_flag ct1.FStarC_Syntax_Syntax.flags
             ct2.FStarC_Syntax_Syntax.flags
         else false
     | uu___ -> false)
and equal_binder (b1 : FStarC_Syntax_Syntax.binder)
  (b2 : FStarC_Syntax_Syntax.binder) : Prims.bool=
  if FStarC_Util.physical_equality b1 b2
  then true
  else
    (let uu___ =
       let uu___1 =
         equal_bv b1.FStarC_Syntax_Syntax.binder_bv
           b2.FStarC_Syntax_Syntax.binder_bv in
       if uu___1
       then
         equal_bqual b1.FStarC_Syntax_Syntax.binder_qual
           b2.FStarC_Syntax_Syntax.binder_qual
       else false in
     if uu___
     then
       equal_list equal_term b1.FStarC_Syntax_Syntax.binder_attrs
         b2.FStarC_Syntax_Syntax.binder_attrs
     else false)
and equal_match_returns
  (x1 :
    (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)))
  (x2 :
    (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=
  let uu___ = x1 in
  match uu___ with
  | (b1, asc1) ->
      let uu___1 = x2 in
      (match uu___1 with
       | (b2, asc2) ->
           let uu___2 = equal_binder b1 b2 in
           if uu___2 then equal_ascription asc1 asc2 else false)
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=
  if FStarC_Util.physical_equality x1 x2
  then true
  else
    (let uu___ = x1 in
     match uu___ with
     | (a1, t1, b1) ->
         let uu___1 = x2 in
         (match uu___1 with
          | (a2, t2, b2) ->
              let uu___2 =
                let uu___3 =
                  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 in
                if uu___3 then equal_opt equal_term t1 t2 else false in
              if uu___2 then b1 = b2 else false))
and equal_letbinding (l1 : FStarC_Syntax_Syntax.letbinding)
  (l2 : FStarC_Syntax_Syntax.letbinding) : Prims.bool=
  if FStarC_Util.physical_equality l1 l2
  then true
  else
    (let uu___ =
       let uu___1 =
         let uu___2 =
           let uu___3 =
             let uu___4 =
               equal_lbname l1.FStarC_Syntax_Syntax.lbname
                 l2.FStarC_Syntax_Syntax.lbname in
             if uu___4
             then
               equal_list FStarC_Ident.ident_equals
                 l1.FStarC_Syntax_Syntax.lbunivs
                 l2.FStarC_Syntax_Syntax.lbunivs
             else false in
           if uu___3
           then
             equal_term l1.FStarC_Syntax_Syntax.lbtyp
               l2.FStarC_Syntax_Syntax.lbtyp
           else false in
         if uu___2
         then
           FStarC_Ident.lid_equals l1.FStarC_Syntax_Syntax.lbeff
             l2.FStarC_Syntax_Syntax.lbeff
         else false in
       if uu___1
       then
         equal_term l1.FStarC_Syntax_Syntax.lbdef
           l2.FStarC_Syntax_Syntax.lbdef
       else false in
     if uu___
     then
       equal_list equal_term l1.FStarC_Syntax_Syntax.lbattrs
         l2.FStarC_Syntax_Syntax.lbattrs
     else false)
and equal_uvar
  (x1 :
    (FStarC_Syntax_Syntax.ctx_uvar * (FStarC_Syntax_Syntax.subst_elt
      Prims.list Prims.list * FStarC_Syntax_Syntax.maybe_set_use_range)))
  (x2 :
    (FStarC_Syntax_Syntax.ctx_uvar * (FStarC_Syntax_Syntax.subst_elt
      Prims.list Prims.list * FStarC_Syntax_Syntax.maybe_set_use_range)))
  : Prims.bool=
  let uu___ = x1 in
  match uu___ with
  | (u1, (s1, uu___1)) ->
      let uu___2 = x2 in
      (match uu___2 with
       | (u2, (s2, uu___3)) ->
           let uu___4 =
             FStarC_Syntax_Unionfind.equiv
               u1.FStarC_Syntax_Syntax.ctx_uvar_head
               u2.FStarC_Syntax_Syntax.ctx_uvar_head in
           if uu___4
           then equal_list (equal_list equal_subst_elt) s1 s2
           else false)
and equal_bv (b1 : FStarC_Syntax_Syntax.bv) (b2 : FStarC_Syntax_Syntax.bv) :
  Prims.bool=
  if FStarC_Util.physical_equality b1 b2
  then true
  else
    if
      FStarC_Ident.ident_equals b1.FStarC_Syntax_Syntax.ppname
        b2.FStarC_Syntax_Syntax.ppname
    then equal_term b1.FStarC_Syntax_Syntax.sort b2.FStarC_Syntax_Syntax.sort
    else false
and equal_fv (f1 : FStarC_Syntax_Syntax.fv) (f2 : FStarC_Syntax_Syntax.fv) :
  Prims.bool=
  if FStarC_Util.physical_equality f1 f2
  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=
  if FStarC_Util.physical_equality u1 u2
  then true
  else
    (let uu___ =
       let uu___1 = FStarC_Syntax_Subst.compress_univ u1 in
       let uu___2 = FStarC_Syntax_Subst.compress_univ u2 in (uu___1, uu___2) in
     match uu___ 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___1 -> false)
and equal_constant (c1 : FStarC_Syntax_Syntax.sconst)
  (c2 : FStarC_Syntax_Syntax.sconst) : Prims.bool=
  if FStarC_Util.physical_equality c1 c2
  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___), FStarC_Const.Const_string
        (s2, uu___1)) -> 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) ->
         (FStarC_Range_Ops.compare r1 r2) = Prims.int_zero
     | (FStarC_Const.Const_reify uu___, FStarC_Const.Const_reify uu___1) ->
         true
     | (FStarC_Const.Const_reflect l1, FStarC_Const.Const_reflect l2) ->
         FStarC_Ident.lid_equals l1 l2
     | uu___ -> 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=
  if FStarC_Util.physical_equality arg1 arg2
  then true
  else
    (let uu___ = arg1 in
     match uu___ with
     | (t1, a1) ->
         let uu___1 = arg2 in
         (match uu___1 with
          | (t2, a2) ->
              let uu___2 = equal_term t1 t2 in
              if uu___2 then equal_opt equal_arg_qualifier a1 a2 else false))
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
  (x1 :
    (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))
  (x2 :
    (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=
  let uu___ = x1 in
  match uu___ with
  | (p1, w1, t1) ->
      let uu___1 = x2 in
      (match uu___1 with
       | (p2, w2, t2) ->
           let uu___2 =
             let uu___3 = equal_pat p1 p2 in
             if uu___3 then equal_opt equal_term w1 w2 else false in
           if uu___2 then equal_term t1 t2 else false)
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=
  if FStarC_Util.physical_equality p1 p2
  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)) ->
         let uu___ =
           let uu___1 = equal_fv fv1 fv2 in
           if uu___1
           then equal_opt (equal_list equal_universe) us1 us2
           else false in
         if uu___
         then equal_list (equal_pair equal_pat equal_poly) args1 args2
         else false
     | (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___ -> 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)) ->
      let uu___ = equal_list equal_term ts1 ts2 in
      if uu___ then equal_list (equal_list equal_arg) args1 args2 else false
  | (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) && ((FStarC_Range_Ops.compare r1 r2) = 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)) ->
      if FStarC_Ident.lid_equals m11 m21 then equal_term t1 t2 else false
  | (FStarC_Syntax_Syntax.Meta_monadic_lift (m11, n1, t1),
     FStarC_Syntax_Syntax.Meta_monadic_lift (m21, n2, t2)) ->
      if (FStarC_Ident.lid_equals m11 m21) && (FStarC_Ident.lid_equals n1 n2)
      then equal_term t1 t2
      else false
  | 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=
  if
    (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))
  then
    equal_list equal_term
      (FStar_Pervasives_Native.snd q1.FStarC_Syntax_Syntax.antiquotations)
      (FStar_Pervasives_Native.snd q2.FStarC_Syntax_Syntax.antiquotations)
  else false
and equal_rc (r1 : FStarC_Syntax_Syntax.residual_comp)
  (r2 : FStarC_Syntax_Syntax.residual_comp) : Prims.bool=
  let uu___ =
    if
      FStarC_Ident.lid_equals r1.FStarC_Syntax_Syntax.residual_effect
        r2.FStarC_Syntax_Syntax.residual_effect
    then
      equal_opt equal_term r1.FStarC_Syntax_Syntax.residual_typ
        r2.FStarC_Syntax_Syntax.residual_typ
    else false in
  if uu___
  then
    equal_list equal_flag r1.FStarC_Syntax_Syntax.residual_flags
      r2.FStarC_Syntax_Syntax.residual_flags
  else false
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')) ->
      let uu___ = equal_term t1 t2 in
      if uu___ then equal_term t1' t2' else false
  | uu___ -> false
and equal_arg_qualifier (a1 : FStarC_Syntax_Syntax.arg_qualifier)
  (a2 : FStarC_Syntax_Syntax.arg_qualifier) : Prims.bool=
  if
    a1.FStarC_Syntax_Syntax.aqual_implicit =
      a2.FStarC_Syntax_Syntax.aqual_implicit
  then
    equal_list equal_term a1.FStarC_Syntax_Syntax.aqual_attributes
      a2.FStarC_Syntax_Syntax.aqual_attributes
  else false
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)) ->
      if i1 = i2 then equal_bv bv1 bv2 else false
  | (FStarC_Syntax_Syntax.NM (bv1, i1), FStarC_Syntax_Syntax.NM (bv2, i2)) ->
      if i1 = i2 then equal_bv bv1 bv2 else false
  | (FStarC_Syntax_Syntax.NT (bv1, t1), FStarC_Syntax_Syntax.NT (bv2, t2)) ->
      let uu___ = equal_bv bv1 bv2 in
      if uu___ then equal_term t1 t2 else false
  | (FStarC_Syntax_Syntax.UN (i1, u1), FStarC_Syntax_Syntax.UN (i2, u2)) ->
      if i1 = i2 then equal_universe u1 u2 else false
  | (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)) ->
      if i1 = i2 then equal_term t1 t2 else false
  | 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 ->
         FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_string
           (FStarC_Ident.string_of_lid l))
  }
let hashable_ident : FStarC_Ident.ident FStarC_Class_Hashable.hashable=
  {
    FStarC_Class_Hashable.hash =
      (fun i ->
         FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_string
           (FStarC_Ident.string_of_id i))
  }
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
         | FStarC_Syntax_Syntax.Eval t ->
             let uu___1 =
               FStarC_Class_Hashable.hash FStarC_Class_Hashable.hashable_int
                 (Prims.of_int 9) 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
