Skip to content

Commit 0c5f5ef

Browse files
committed
Add an assertion in of_term_cst
1 parent 855e6d4 commit 0c5f5ef

5 files changed

Lines changed: 41 additions & 17 deletions

File tree

src/lib/frontend/d_cnf.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -587,10 +587,11 @@ and handle_ty_app ?(update = false) ty_c l =
587587
let mk_ty_decl (ty_c: DE.ty_cst) =
588588
match DT.definition ty_c with
589589
| Some (
590-
Adt { cases = [| { cstr = { id_ty; _ } as cstr; dstrs; _ } |]; _ }
590+
(Adt { cases = [| { cstr = { id_ty; _ } as cstr; dstrs; _ } |]; _ } as adt)
591591
) ->
592592
(* Records and adts that only have one case are treated in the same way,
593593
and considered as records. *)
594+
Nest.attach_orders [adt];
594595
let uid = Uid.of_ty_cst ty_c in
595596
let tyvl = Cache.store_ty_vars_ret id_ty in
596597
let rev_lbs =
@@ -613,8 +614,8 @@ let mk_ty_decl (ty_c: DE.ty_cst) =
613614
Cache.store_ty ty_c ty
614615

615616
| Some (Adt { cases; _ } as adt) ->
616-
let uid = Uid.of_ty_cst ty_c in
617617
Nest.attach_orders [adt];
618+
let uid = Uid.of_ty_cst ty_c in
618619
let tyvl = Cache.store_ty_vars_ret cases.(0).cstr.id_ty in
619620
Cache.store_ty ty_c (Ty.t_adt uid tyvl);
620621
let rev_cs =

src/lib/structures/uid.ml

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,17 +38,31 @@ type term_cst = DE.term_cst t
3838
type ty_cst = DE.ty_cst t
3939
type ty_var = DE.ty_var t
4040

41-
let[@inline always] of_term_cst id = Term_cst id
41+
let order_tag : int DStd.Tag.t = DStd.Tag.create ()
42+
43+
let has_order id =
44+
let is_cstr DE.{ builtin; _ } =
45+
match builtin with
46+
| DStd.Builtin.Constructor _ -> true
47+
| _ -> false
48+
in
49+
let has_attached_order id =
50+
DE.Term.Const.get_tag id order_tag |> Option.is_some
51+
in
52+
(not (is_cstr id)) || has_attached_order id
53+
54+
let[@inline always] of_term_cst id =
55+
(* This assertion ensures that the API of the [Nest] module have been
56+
correctly used, that is [Nest.attach_orders] have been called on
57+
the nest of [id] if [id] is a constructor of ADT. *)
58+
if not @@ has_order id then Fmt.failwith "not order on %a" DE.Id.print id;
59+
Term_cst id
60+
4261
let[@inline always] of_ty_cst id = Ty_cst id
4362
let[@inline always] of_ty_var id = Ty_var id
4463
let[@inline always] of_hstring hs = Hstring hs
4564
let[@inline always] of_string s = of_hstring @@ Hstring.make s
4665

47-
let[@inline always] to_term_cst id =
48-
match id with
49-
| Term_cst t -> t
50-
| _ -> invalid_arg "to_term_cst"
51-
5266
let hash (type a) (u : a t) =
5367
match u with
5468
| Hstring hs -> Hstring.hash hs

src/lib/structures/uid.mli

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,14 @@ val of_ty_var : DE.ty_var -> ty_var
4343
val of_string : string -> 'a t
4444
val of_hstring : Hstring.t -> 'a t
4545

46-
val to_term_cst : term_cst -> DE.term_cst
47-
4846
val hash : 'a t -> int
4947
val pp : 'a t Fmt.t
5048
val show : 'a t -> string
5149
val equal : 'a t -> 'a t -> bool
5250
val compare : 'a t -> 'a t -> int
5351

52+
val order_tag : int Dolmen.Std.Tag.t
53+
(** Tag used to attach the order of constructor. *)
54+
5455
module Term_set : Set.S with type elt = term_cst
5556
module Ty_map : Map.S with type key = ty_cst

src/lib/util/nest.ml

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,10 +153,6 @@ let ty_cst_of_cstr DE.{ builtin; _ } =
153153
| B.Constructor { adt; _ } -> adt
154154
| _ -> Fmt.failwith "expect an ADT constructor"
155155

156-
(** Tag used to attach the order of constructor. Used to
157-
retrieve efficiency the order of the constructor in [to_int]. *)
158-
let order_tag : int DStd.Tag.t = DStd.Tag.create ()
159-
160156
let attach_orders defs =
161157
let hp = build_graph defs in
162158
let r : (int * DE.term_cst list) H.t = H.create 17 in
@@ -166,7 +162,7 @@ let attach_orders defs =
166162
let { id; outgoing; in_degree; _ } = Hp.pop_min hp in
167163
let ty = ty_cst_of_cstr id in
168164
let o = H.add_cstr r ty id in
169-
DE.Term.Const.set_tag id order_tag o;
165+
DE.Term.Const.set_tag id Uid.order_tag o;
170166
assert (in_degree = 0);
171167
List.iter
172168
(fun node ->
@@ -180,8 +176,15 @@ let attach_orders defs =
180176

181177
let perfect_hash id =
182178
match (id : _ Uid.t) with
183-
| Term_cst id ->
184-
Option.get @@ DE.Term.Const.get_tag id order_tag
179+
| Term_cst ({ builtin = B.Constructor _; _ } as id) ->
180+
begin match DE.Term.Const.get_tag id Uid.order_tag with
181+
| Some h -> h
182+
| None ->
183+
(* Cannot occur as we eliminate this case in the smart constructor
184+
[Uid.of_term_cst]. *)
185+
assert false
186+
end
187+
| Term_cst _ -> invalid_arg "Nest.perfect_hash"
185188
| Hstring hs ->
186189
Hstring.hash hs
187190
| _ -> .

src/lib/util/nest.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,8 @@ val attach_orders : DE.ty_def list -> unit
3737
mutually recursive definition of ADTs. *)
3838

3939
val perfect_hash : Uid.term_cst -> int
40+
(** [perfect_hash u] returns an integer between [0] and [n] exclusive where
41+
[u] is a constructor and [n] is the number of constructors of the ADT of
42+
[u].
43+
44+
@raise Invalid_arg if [u] is not a constructor. *)

0 commit comments

Comments
 (0)