-
Notifications
You must be signed in to change notification settings - Fork 37
Use Dolmen attribute to store well founded order #1153
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 7 commits
6743244
7ac984a
f421b43
39ba617
30e7141
02d9834
8951c2b
2b11a43
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -101,20 +101,20 @@ module Cache = struct | |||||||||||||||||||
| let find_ty id = | ||||||||||||||||||||
| HT.find ae_ty_ht (Id id) | ||||||||||||||||||||
|
|
||||||||||||||||||||
| let fresh_ty ?(is_var = true) ?id () = | ||||||||||||||||||||
| let fresh_ty ?(is_var = true) ?(name = None) () = | ||||||||||||||||||||
| if is_var | ||||||||||||||||||||
| then Ty.fresh_tvar () | ||||||||||||||||||||
| else | ||||||||||||||||||||
| match id with | ||||||||||||||||||||
| | Some id -> Ty.text [] (Uid.of_dolmen id) | ||||||||||||||||||||
| match name with | ||||||||||||||||||||
| | Some n -> Ty.text [] (Uid.of_string n) | ||||||||||||||||||||
| | None -> Ty.fresh_empty_text () | ||||||||||||||||||||
|
|
||||||||||||||||||||
| let update_ty_store ?(is_var = true) id = | ||||||||||||||||||||
| let ty = fresh_ty ~is_var ~id () in | ||||||||||||||||||||
| let update_ty_store ?(is_var = true) ?name id = | ||||||||||||||||||||
| let ty = fresh_ty ~is_var ~name () in | ||||||||||||||||||||
| store_ty id ty | ||||||||||||||||||||
|
|
||||||||||||||||||||
| let update_ty_store_ret ?(is_var = true) id = | ||||||||||||||||||||
| let ty = fresh_ty ~is_var ~id () in | ||||||||||||||||||||
| let update_ty_store_ret ?(is_var = true) ?name id = | ||||||||||||||||||||
| let ty = fresh_ty ~is_var ~name () in | ||||||||||||||||||||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using a polymorphic GADT for It makes sense to use I rollback my modifications done in #1098. |
||||||||||||||||||||
| store_ty id ty; | ||||||||||||||||||||
| ty | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -125,7 +125,8 @@ module Cache = struct | |||||||||||||||||||
| update_ty_store_ret ~is_var id | ||||||||||||||||||||
|
|
||||||||||||||||||||
| let store_tyv ?(is_var = true) t_v = | ||||||||||||||||||||
| update_ty_store ~is_var t_v | ||||||||||||||||||||
| let name = get_basename t_v.DE.path in | ||||||||||||||||||||
| update_ty_store ~is_var ~name t_v | ||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Alternatively, we can create an identifier from the name of the variable:
Suggested change
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| let store_tyvl ?(is_var = true) (tyvl: DE.ty_var list) = | ||||||||||||||||||||
| List.iter (store_tyv ~is_var) tyvl | ||||||||||||||||||||
|
|
@@ -585,19 +586,21 @@ and handle_ty_app ?(update = false) ty_c l = | |||||||||||||||||||
| let mk_ty_decl (ty_c: DE.ty_cst) = | ||||||||||||||||||||
| match DT.definition ty_c with | ||||||||||||||||||||
| | Some ( | ||||||||||||||||||||
| Adt { cases = [| { cstr = { id_ty; _ } as cstr; dstrs; _ } |]; _ } as adt | ||||||||||||||||||||
| (Adt | ||||||||||||||||||||
| { cases = [| { cstr = { id_ty; _ } as cstr; dstrs; _ } |]; _ } as adt) | ||||||||||||||||||||
| ) -> | ||||||||||||||||||||
| (* Records and adts that only have one case are treated in the same way, | ||||||||||||||||||||
| and considered as records. *) | ||||||||||||||||||||
| Nest.add_nest [adt]; | ||||||||||||||||||||
| Nest.attach_orders [adt]; | ||||||||||||||||||||
| let uid = Uid.of_ty_cst ty_c in | ||||||||||||||||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why no
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Because we never send record values to the ADT theory so we never use the total order.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Makes sense — the order is also trivial. I think it still makes sense to have an order attached to all constructors for consistency.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I did this modification. We have an order on all constructors because we check it in |
||||||||||||||||||||
| let tyvl = Cache.store_ty_vars_ret id_ty in | ||||||||||||||||||||
| let rev_lbs = | ||||||||||||||||||||
| Array.fold_left ( | ||||||||||||||||||||
| fun acc c -> | ||||||||||||||||||||
| match c with | ||||||||||||||||||||
| | Some (DE.{ id_ty; _ } as id) -> | ||||||||||||||||||||
| let pty = dty_to_ty id_ty in | ||||||||||||||||||||
| (Uid.of_dolmen id, pty) :: acc | ||||||||||||||||||||
| (Uid.of_term_cst id, pty) :: acc | ||||||||||||||||||||
| | _ -> | ||||||||||||||||||||
| Fmt.failwith | ||||||||||||||||||||
| "Unexpected null label for some field of the record type %a" | ||||||||||||||||||||
|
|
@@ -606,13 +609,13 @@ let mk_ty_decl (ty_c: DE.ty_cst) = | |||||||||||||||||||
| ) [] dstrs | ||||||||||||||||||||
| in | ||||||||||||||||||||
| let lbs = List.rev rev_lbs in | ||||||||||||||||||||
| let record_constr = Uid.of_dolmen cstr in | ||||||||||||||||||||
| let ty = Ty.trecord ~record_constr tyvl (Uid.of_dolmen ty_c) lbs in | ||||||||||||||||||||
| let record_constr = Uid.of_term_cst cstr in | ||||||||||||||||||||
| let ty = Ty.trecord ~record_constr tyvl uid lbs in | ||||||||||||||||||||
| Cache.store_ty ty_c ty | ||||||||||||||||||||
|
|
||||||||||||||||||||
| | Some (Adt { cases; _ } as adt) -> | ||||||||||||||||||||
| Nest.add_nest [adt]; | ||||||||||||||||||||
| let uid = Uid.of_dolmen ty_c in | ||||||||||||||||||||
| Nest.attach_orders [adt]; | ||||||||||||||||||||
| let uid = Uid.of_ty_cst ty_c in | ||||||||||||||||||||
| let tyvl = Cache.store_ty_vars_ret cases.(0).cstr.id_ty in | ||||||||||||||||||||
| Cache.store_ty ty_c (Ty.t_adt uid tyvl); | ||||||||||||||||||||
| let rev_cs = | ||||||||||||||||||||
|
|
@@ -623,11 +626,11 @@ let mk_ty_decl (ty_c: DE.ty_cst) = | |||||||||||||||||||
| fun acc tc_o -> | ||||||||||||||||||||
| match tc_o with | ||||||||||||||||||||
| | Some (DE.{ id_ty; _ } as field) -> | ||||||||||||||||||||
| (Uid.of_dolmen field, dty_to_ty id_ty) :: acc | ||||||||||||||||||||
| (Uid.of_term_cst field, dty_to_ty id_ty) :: acc | ||||||||||||||||||||
| | None -> assert false | ||||||||||||||||||||
| ) [] dstrs | ||||||||||||||||||||
| in | ||||||||||||||||||||
| (Uid.of_dolmen cstr, List.rev rev_fields) :: accl | ||||||||||||||||||||
| (Uid.of_term_cst cstr, List.rev rev_fields) :: accl | ||||||||||||||||||||
| ) [] cases | ||||||||||||||||||||
| in | ||||||||||||||||||||
| let body = Some (List.rev rev_cs) in | ||||||||||||||||||||
|
|
@@ -638,7 +641,7 @@ let mk_ty_decl (ty_c: DE.ty_cst) = | |||||||||||||||||||
| let ty_params = [] | ||||||||||||||||||||
| (* List.init ty_c.id_ty.arity (fun _ -> Ty.fresh_tvar ()) *) | ||||||||||||||||||||
| in | ||||||||||||||||||||
| let ty = Ty.text ty_params (Uid.of_dolmen ty_c) in | ||||||||||||||||||||
| let ty = Ty.text ty_params (Uid.of_ty_cst ty_c) in | ||||||||||||||||||||
| Cache.store_ty ty_c ty | ||||||||||||||||||||
|
|
||||||||||||||||||||
| (** Handles term declaration by storing the eventual present type variables | ||||||||||||||||||||
|
|
@@ -678,7 +681,7 @@ let mk_mr_ty_decls (tdl: DE.ty_cst list) = | |||||||||||||||||||
| match c with | ||||||||||||||||||||
| | Some (DE.{ id_ty; _ } as id) -> | ||||||||||||||||||||
| let pty = dty_to_ty id_ty in | ||||||||||||||||||||
| (Uid.of_dolmen id, pty) :: acc | ||||||||||||||||||||
| (Uid.of_term_cst id, pty) :: acc | ||||||||||||||||||||
| | _ -> | ||||||||||||||||||||
| Fmt.failwith | ||||||||||||||||||||
| "Unexpected null label for some field of the record type %a" | ||||||||||||||||||||
|
|
@@ -700,11 +703,11 @@ let mk_mr_ty_decls (tdl: DE.ty_cst list) = | |||||||||||||||||||
| fun acc tc_o -> | ||||||||||||||||||||
| match tc_o with | ||||||||||||||||||||
| | Some (DE.{ id_ty; _ } as id) -> | ||||||||||||||||||||
| (Uid.of_dolmen id, dty_to_ty id_ty) :: acc | ||||||||||||||||||||
| (Uid.of_term_cst id, dty_to_ty id_ty) :: acc | ||||||||||||||||||||
| | None -> assert false | ||||||||||||||||||||
| ) [] dstrs | ||||||||||||||||||||
| in | ||||||||||||||||||||
| (Uid.of_dolmen cstr, List.rev rev_fields) :: accl | ||||||||||||||||||||
| (Uid.of_term_cst cstr, List.rev rev_fields) :: accl | ||||||||||||||||||||
| ) [] cases | ||||||||||||||||||||
| in | ||||||||||||||||||||
| let body = Some (List.rev rev_cs) in | ||||||||||||||||||||
|
|
@@ -729,18 +732,19 @@ let mk_mr_ty_decls (tdl: DE.ty_cst list) = | |||||||||||||||||||
| assert false | ||||||||||||||||||||
| ) ([], false) tdl | ||||||||||||||||||||
| in | ||||||||||||||||||||
| Nest.add_nest rev_tdefs; | ||||||||||||||||||||
| Nest.attach_orders rev_tdefs; | ||||||||||||||||||||
| let rev_l = | ||||||||||||||||||||
| List.fold_left ( | ||||||||||||||||||||
| fun acc tdef -> | ||||||||||||||||||||
| match tdef with | ||||||||||||||||||||
| | DE.Adt { cases; record; ty = ty_c; } as adt -> | ||||||||||||||||||||
| let tyvl = Cache.store_ty_vars_ret cases.(0).cstr.id_ty in | ||||||||||||||||||||
| let uid = Uid.of_dolmen ty_c in | ||||||||||||||||||||
| let uid = Uid.of_ty_cst ty_c in | ||||||||||||||||||||
| let record_constr = Uid.of_term_cst cases.(0).cstr in | ||||||||||||||||||||
| let ty = | ||||||||||||||||||||
| if (record || Array.length cases = 1) && not contains_adts | ||||||||||||||||||||
| then | ||||||||||||||||||||
| Ty.trecord ~record_constr:uid tyvl uid [] | ||||||||||||||||||||
| Ty.trecord ~record_constr tyvl uid [] | ||||||||||||||||||||
| else | ||||||||||||||||||||
| Ty.t_adt uid tyvl | ||||||||||||||||||||
| in | ||||||||||||||||||||
|
|
@@ -793,7 +797,7 @@ let mk_pattern DE.{ term_descr; _ } = | |||||||||||||||||||
| Array.fold_left ( | ||||||||||||||||||||
| fun acc v -> | ||||||||||||||||||||
| match v with | ||||||||||||||||||||
| | Some dstr -> Uid.of_dolmen dstr :: acc | ||||||||||||||||||||
| | Some dstr -> Uid.of_term_cst dstr :: acc | ||||||||||||||||||||
| | _ -> assert false | ||||||||||||||||||||
| ) [] dstrs | ||||||||||||||||||||
| | _ -> | ||||||||||||||||||||
|
|
@@ -811,10 +815,10 @@ let mk_pattern DE.{ term_descr; _ } = | |||||||||||||||||||
| ) [] (List.rev rev_vnames) pargs | ||||||||||||||||||||
| in | ||||||||||||||||||||
| let args = List.rev rev_args in | ||||||||||||||||||||
| Typed.Constr {name = Uid.of_dolmen cst; args} | ||||||||||||||||||||
| Typed.Constr {name = Uid.of_term_cst cst; args} | ||||||||||||||||||||
|
|
||||||||||||||||||||
| | Cst ({ builtin = B.Constructor _; _ } as cst) -> | ||||||||||||||||||||
| Typed.Constr {name = Uid.of_dolmen cst; args = []} | ||||||||||||||||||||
| Typed.Constr {name = Uid.of_term_cst cst; args = []} | ||||||||||||||||||||
|
|
||||||||||||||||||||
| | Var ({ builtin = B.Base; path; _ } as t_v) -> | ||||||||||||||||||||
| (* Should the type be passed as an argument | ||||||||||||||||||||
|
|
@@ -974,7 +978,7 @@ let rec mk_expr | |||||||||||||||||||
| | Trecord _ as ty -> | ||||||||||||||||||||
| E.mk_record [] ty | ||||||||||||||||||||
| | Tadt _ as ty -> | ||||||||||||||||||||
| E.mk_constr (Uid.of_dolmen tcst) [] ty | ||||||||||||||||||||
| E.mk_constr (Uid.of_term_cst tcst) [] ty | ||||||||||||||||||||
| | ty -> | ||||||||||||||||||||
| Fmt.failwith "unexpected type %a@." Ty.print ty | ||||||||||||||||||||
| end | ||||||||||||||||||||
|
|
@@ -1019,9 +1023,9 @@ let rec mk_expr | |||||||||||||||||||
| let sy = | ||||||||||||||||||||
| match Cache.find_ty adt with | ||||||||||||||||||||
| | Trecord _ -> | ||||||||||||||||||||
| Sy.Op (Sy.Access (Uid.of_dolmen destr)) | ||||||||||||||||||||
| Sy.Op (Sy.Access (Uid.of_term_cst destr)) | ||||||||||||||||||||
| | Tadt _ -> | ||||||||||||||||||||
| Sy.destruct (Uid.of_dolmen destr) | ||||||||||||||||||||
| Sy.destruct (Uid.of_term_cst destr) | ||||||||||||||||||||
| | _ -> assert false | ||||||||||||||||||||
| in | ||||||||||||||||||||
| E.mk_term sy [e] ty | ||||||||||||||||||||
|
|
@@ -1041,7 +1045,7 @@ let rec mk_expr | |||||||||||||||||||
| cstr = { builtin = B.Constructor { adt; _ }; _ } as cstr; _ | ||||||||||||||||||||
| }, [x] -> | ||||||||||||||||||||
| begin | ||||||||||||||||||||
| let builtin = Sy.IsConstr (Uid.of_dolmen cstr) in | ||||||||||||||||||||
| let builtin = Sy.IsConstr (Uid.of_term_cst cstr) in | ||||||||||||||||||||
| let ty_c = | ||||||||||||||||||||
| match DT.definition adt with | ||||||||||||||||||||
| | Some ( | ||||||||||||||||||||
|
|
@@ -1326,9 +1330,8 @@ let rec mk_expr | |||||||||||||||||||
| let ty = dty_to_ty term_ty in | ||||||||||||||||||||
| begin match ty with | ||||||||||||||||||||
| | Ty.Tadt _ -> | ||||||||||||||||||||
| let sy = Sy.constr @@ Uid.of_dolmen tcst in | ||||||||||||||||||||
| let l = List.map (fun t -> aux_mk_expr t) args in | ||||||||||||||||||||
| E.mk_term sy l ty | ||||||||||||||||||||
| E.mk_constr (Uid.of_term_cst tcst) l ty | ||||||||||||||||||||
| | Ty.Trecord _ -> | ||||||||||||||||||||
| let l = List.map (fun t -> aux_mk_expr t) args in | ||||||||||||||||||||
| E.mk_record l ty | ||||||||||||||||||||
|
|
||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this might re-introduce some of the potential name clashes that #1098 was intended to remove.
When converting a variable → type for the purpose of quantifier elimination, we should fall back to the
Ty.fresh_empty_text ()here — see my comment instore_tyvbelow.