Skip to content

Commit 52ca4d9

Browse files
garesptorrx
andcommitted
wrapping [wip]
Co-Authored-by: ptorrx <[email protected]>
1 parent dce339f commit 52ca4d9

18 files changed

+934
-85
lines changed

HB/common/database.elpi

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,10 @@ pred module-to-export_module-nice i:prop, o:id.
5151
module-to-export_module-nice (module-to-export _ M _) M.
5252

5353
pred instance-to-export_instance i:prop, o:constant.
54-
instance-to-export_instance (instance-to-export _ _ M) M.
54+
instance-to-export_instance (instance-to-export _ M) M.
5555

5656
pred instance-to-export_instance-nice i:prop, o:id.
57-
instance-to-export_instance-nice (instance-to-export _ M _) M.
57+
instance-to-export_instance-nice (instance-to-export _ M) ID :- coq.gref->id (const M) ID.
5858

5959
pred abbrev-to-export_name i:prop, o:id.
6060
abbrev-to-export_name (abbrev-to-export _ N _) N.
@@ -181,6 +181,8 @@ toposort-proj.acc Proj ES Acc [A|In] Out :- std.do![
181181
topo-find B A => toposort-proj.acc Proj ES [B|Acc] In Out
182182
].
183183

184+
% TODO: check if topo-find-all is really needed
185+
184186
% Classes can be topologically sorted according to the subclass relation
185187
pred toposort-classes.mk-class-edge i:prop, o:pair classname classname.
186188
toposort-classes.mk-class-edge (sub-class C1 C2 _ _) (pr C2 C1).
@@ -435,12 +437,15 @@ structure-nparams Structure NParams :-
435437
factory-nparams Class NParams.
436438

437439
pred factory? i:term, o:w-args factoryname.
438-
factory? S (triple F Params T) :-
440+
factory? S (triple F Params T) :- factory?-split S F [_|Params] T _.
441+
442+
pred factory?-split i:term, o:factoryname, o:list term, o:term, o:list term.
443+
factory?-split S F [global GR|Params] T Rest :-
439444
not (var S), !,
440445
safe-dest-app S (global GR) Args,
441446
factory-alias->gref GR F ok,
442447
factory-nparams F NP, !,
443-
std.split-at NP Args Params [T|_].
448+
std.split-at NP Args Params [T|Rest].
444449

445450
% [find-max-classes Mixins Classes] states that Classes is a list of classes
446451
% which contain all the mixins in Mixins.
@@ -460,3 +465,8 @@ find-max-classes [M|Mixins] [C|Classes] :-
460465
].
461466
find-max-classes [M|_] _ :- coq.error "HB: cannot find a class containing mixin" M.
462467

468+
pred is-subject-lifter i:term, o:int, o:classname.
469+
is-subject-lifter (global (const C)) N Class :- exported-op M _ C, wrapper-mixin _ (const C) _, factory-nparams M N, mixin-first-class M Class.
470+
is-subject-lifter (app[global (const C)|_]) N Class :- exported-op M _ C, wrapper-mixin _ (const C) _, factory-nparams M N, mixin-first-class M Class.
471+
is-subject-lifter (global GR) N Class :- tag GR Class N, wrapper-mixin _ GR _.
472+
is-subject-lifter (app[global GR|_]) N Class :- tag GR Class N, wrapper-mixin _ GR _.

HB/common/synthesis.elpi

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,13 @@ infer-all-args-let Ps T GR X Diag :- std.do! [
7474
private.instantiate-all-args-let FT T X Diag,
7575
].
7676

77+
pred try-infer-all-args-let i:list term, i:term, i:gref, o:term.
78+
try-infer-all-args-let Ps T GR X :- std.do! [
79+
coq.env.typeof GR Ty,
80+
coq.mk-eta (-1) Ty (global GR) EtaF,
81+
coq.subst-fun {std.append Ps [T]} EtaF FT,
82+
private.try-instantiate-all-args-let FT T X,
83+
].
7784

7885
% [assert!-infer-mixin TheType M Out] infers one mixin M on TheType and
7986
% aborts with an error message if the mixin cannot be inferred
@@ -112,6 +119,17 @@ under-mixin-src-from-factory.do! TheType TheFactory LP :- std.do! [
112119
MLClauses => std.do! LP
113120
].
114121

122+
123+
% Given TheType makes the provided list of mixins and instances
124+
% available for inference.
125+
pred under-these-mixin-src.do! i:term, i:list mixinname, i:list constant, o:list prop, i:list prop.
126+
under-these-mixin-src.do! TheType ML TheMixins ClausesHas LP :- std.do! [
127+
std.map2 ML TheMixins (m\mi\c\ c = mixin-src TheType m (global (const mi))) MLClauses,
128+
std.map-filter MLClauses mixin-src->has-mixin-instance ClausesHas,
129+
MLClauses => std.do! LP
130+
].
131+
132+
115133
% Given TheType and a factory instance (on it), builds all the *new* mixins
116134
% provided by the factory available for and passes them to the given
117135
% continuation
@@ -251,6 +269,7 @@ instantiate-all-these-mixin-args (fun _ Tm F) T ML R :-
251269
coq.safe-dest-app Tm (global TmGR) _,
252270
factory-alias->gref TmGR M ok,
253271
std.mem! ML M,
272+
factory? Tm (triple _ _ Subj), Subj = T, % check the subject is T (do not pass T to factory?)
254273
!,
255274
if (mixin-for T M X) true (coq.error "HB: Unable to find mixin" {nice-gref->string M} "on subject" {coq.term->string T}), !,
256275
instantiate-all-these-mixin-args (F X) T ML R.
@@ -270,6 +289,16 @@ instantiate-all-args-let (fun N Tm F) T (let N Tm X R) Diag :- !, std.do! [
270289
].
271290
instantiate-all-args-let F _ F ok.
272291

292+
pred try-instantiate-all-args-let i:term, i:term, o:term.
293+
try-instantiate-all-args-let (fun N Tm F) T (let N Tm X R) :- !, std.do! [
294+
coq.safe-dest-app Tm (global TmGR) _,
295+
factory-alias->gref TmGR M ok,
296+
(mixin-for T M X ; true),
297+
(@pi-def N Tm X m\ try-instantiate-all-args-let (F m) T (R m)),
298+
].
299+
try-instantiate-all-args-let F _ F.
300+
301+
273302
% [structure-instance->mixin-srcs TheType Structure] finds a CS instance for
274303
% Structure on TheType (if any) and builds mixin-src clauses for all the mixins
275304
% which can be candidates from that class instance. It finds instances which are

HB/common/utils-synterp.elpi

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ with-attributes P :-
2424
att "primitive" bool,
2525
att "non_forgetful_inheritance" bool,
2626
att "hnf" bool,
27-
] Opts, !,
27+
att "wrapper" bool,
28+
att "unsafe.univ" bool,
29+
] Opts, !,
2830
Opts => (save-docstring, P).
2931

3032
pred if-verbose i:prop.

HB/common/utils.elpi

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ gref->modname GR NComp Sep ModName :-
7676
std.length Path Len,
7777
if (Len >= NComp) true (coq.error "Not enough enclosing modules for" {coq.gref->string GR}),
7878
std.take NComp Mods L,
79-
std.string.concat Sep {std.rev L} ModName.
79+
std.string.concat Sep {std.rev L} ModName. % TODO: check if the new_int is needed
8080
pred gref->modname-label i:gref, i:int, i:string, o:string.
8181
gref->modname-label GR NComp Sep ModName :-
8282
coq.gref->path GR Path,
@@ -294,7 +294,7 @@ pack? (indc K) C :-
294294
coq.env.indc K _ _ _ KTy, prod-last-gref KTy (indt I), % TODO: use new API
295295
class-def (class C (indt I) _).
296296

297-
pred distribute-w-params i:list-w-params A, o:list (one-w-params A).
297+
pred distribute-w-params i:w-params (list A), o:list (w-params A).
298298
distribute-w-params (w-params.cons N T F) L :-
299299
pi x\ distribute-w-params (F x) (L1 x), std.map (L1 x) (bind-cons N T x) L.
300300
distribute-w-params (w-params.nil N T F) L :-
@@ -316,6 +316,18 @@ re-enable-id-phant T T1 :-
316316
(pi f1 f2 t v\ copy {{lib:@hb.ignore_disabled lp:t lp:f1 lp:v lp:f2}} {{lib:@hb.ignore lp:t lp:v}} :- !) =>
317317
copy T T1.
318318

319+
pred disable-id-phant-indt-decl i:indt-decl, o:indt-decl.
320+
disable-id-phant-indt-decl D D1 :-
321+
(pi fresh fresh1 t v\ copy {{lib:@hb.id lp:t lp:v}} {{lib:@hb.id_disabled lp:t lp:fresh lp:v lp:fresh1}} :- !) =>
322+
(pi fresh fresh1 t v\ copy {{lib:@hb.ignore lp:t lp:v}} {{lib:@hb.ignore_disabled lp:t lp:fresh lp:v lp:fresh1}} :- !) =>
323+
copy-indt-decl D D1.
324+
325+
pred re-enable-id-phant-indt-decl i:indt-decl, o:indt-decl.
326+
re-enable-id-phant-indt-decl D D1 :-
327+
(pi f1 f2 t v\ copy {{lib:@hb.id_disabled lp:t lp:f1 lp:v lp:f2}} {{lib:@hb.id lp:t lp:v}} :- !) =>
328+
(pi f1 f2 t v\ copy {{lib:@hb.ignore_disabled lp:t lp:f1 lp:v lp:f2}} {{lib:@hb.ignore lp:t lp:v}} :- !) =>
329+
copy-indt-decl D D1.
330+
319331
pred prod-last i:term, o:term.
320332
prod-last (prod N S X) Y :- !, @pi-decl N S x\ prod-last (X x) Y.
321333
prod-last X X :- !.

HB/context.elpi

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,40 @@ namespace private {
5757
% to the corresponding mixin using mixin-for
5858
pred postulate-mixin i:term, i:w-args mixinname, i:triple (list constant) (list prop) (list (w-args mixinname)),
5959
o:triple (list constant) (list prop) (list (w-args mixinname)).
60+
61+
postulate-mixin TheType (triple M Ps T) (triple CL MSL MLwP) (triple OutCL [MC|MSL] [NewMwP|MLwP]) :- wrapper-mixin M _ _, !, MSL => std.do! [
62+
NameVar is "local_mixin_private_" ^ {gref->modname M 2 "_"},
63+
NameMixin is "local_mixin_" ^ {gref->modname M 2 "_"},
64+
65+
if-verbose (coq.say "HB: postulate and wrap" NameVar "on" {coq.term->string T}),
66+
67+
synthesis.infer-all-gref-deps Ps T M TySkel,
68+
% was synthesis.infer-all-mixin-args Ps T M TySkel,
69+
% if-verbose (coq.say "HB: postulate-mixin checking" TySkel),
70+
% std.assert-ok! (coq.typecheck Ty _) "postulate-mixin: Ty illtyped",
71+
std.assert-ok! (coq.elaborate-ty-skeleton TySkel _ Ty)
72+
"postulate-mixin: Ty illtyped",
73+
74+
Ty = app[global M|Args],
75+
factory-constructor M K,
76+
coq.mk-app (global K) Args KArgs,
77+
std.assert-ok! (coq.typecheck KArgs {{ lp:VarTy -> _ }}) "brrr",
78+
79+
log.coq.env.add-section-variable-noimplicits NameVar VarTy V,
80+
81+
coq.mk-app KArgs [global (const V)] TheMixin,
82+
83+
log.coq.env.add-const-noimplicits NameMixin TheMixin Ty @transparent! C,
84+
85+
factory? Ty NewMwP,
86+
87+
declare-instances-from-postulated-mixin TheType M T C MC NewCL,
88+
89+
std.append CL NewCL OutCL,
90+
91+
].
92+
93+
6094
postulate-mixin TheType (triple M Ps T) (triple CL MSL MLwP) (triple OutCL [MC|MSL] [NewMwP|MLwP]) :- MSL => std.do! [
6195
Name is "local_mixin_" ^ {gref->modname M 2 "_"},
6296

@@ -70,11 +104,19 @@ postulate-mixin TheType (triple M Ps T) (triple CL MSL MLwP) (triple OutCL [MC|M
70104
"postulate-mixin: Ty illtyped",
71105
log.coq.env.add-section-variable-noimplicits Name Ty C,
72106
factory? Ty NewMwP,
107+
108+
declare-instances-from-postulated-mixin TheType M T C MC NewCL,
109+
110+
std.append CL NewCL OutCL,
111+
112+
].
113+
114+
pred declare-instances-from-postulated-mixin i:term, i:mixinname, i:term, i:constant, o:prop, o:list constant.
115+
declare-instances-from-postulated-mixin TheType M T C MC NewCL :- std.do! [
73116

74117
MC = mixin-src T M (global (const C)),
75118
MC => get-option "local" tt =>
76-
instance.declare-all TheType {findall-classes-for [M]} NewCSL,
77-
std.map NewCSL snd NewCL,
78-
std.append CL NewCL OutCL
79-
].
119+
instance.declare-all TheType {findall-classes-for [M]} NewCL,
120+
].
121+
80122
}}

HB/export.elpi

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export.reexport-all-modules-and-CS Filter :- std.do! [
4747
std.forall2 NiceMods Mods log.coq.env.export-module,
4848

4949

50-
std.findall (instance-to-export File NiceInstance_ Const_) InstCL,
50+
std.findall (instance-to-export File Const_) InstCL,
5151
std.filter {std.list-uniq InstCL} (export.private.instance-in-module MFilter) InstCLFiltered,
5252
std.map InstCLFiltered instance-to-export_instance Insts,
5353

@@ -83,7 +83,7 @@ module-in-module PM (module-to-export _ _ M) :-
8383
std.appendR PM _ PC. % sublist
8484

8585
pred instance-in-module i:list string, i:prop.
86-
instance-in-module PM (instance-to-export _ _ C) :-
86+
instance-in-module PM (instance-to-export _ C) :-
8787
coq.gref->path (const C) PC,
8888
std.appendR PM _ PC. % sublist
8989

HB/factory.elpi

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,53 @@ declare-asset Arg AssetKind :- std.do! [
226226
)
227227
].
228228

229+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
230+
%%% auxiliary code for wrapper-mixin
231+
232+
pred extract_from_record_decl i: (term -> gref -> prop), i:indt-decl, o:gref.
233+
extract_from_record_decl P (parameter ID _ Ty R) Out :-
234+
@pi-parameter ID Ty p\
235+
extract_from_record_decl P (R p) Out.
236+
extract_from_record_decl P (record _ _ _ (field _ _ Ty (x\end-record))) GR0 :-
237+
P Ty GR0.
238+
239+
pred extract_from_rtty i: (term -> gref -> prop), i: term, o:gref.
240+
extract_from_rtty P (prod N Ty TF) Out1 :-
241+
@pi-decl N Ty p\
242+
extract_from_rtty P (TF p) Out1.
243+
extract_from_rtty P Ty Gr :- P Ty Gr.
244+
245+
pred xtr_fst_op i:term, o:gref.
246+
xtr_fst_op Ty Gr1 :-
247+
Ty = (app [global Gr0| _]),
248+
factory-alias->gref Gr0 Gr1 ok.
249+
250+
pred xtr_snd_op i:term, o:gref.
251+
xtr_snd_op Ty Gr :-
252+
% TODO: use factory? from database.elpi
253+
Ty = (app [global Gr0| Args]),
254+
factory-alias->gref Gr0 Gr1 ok,
255+
factory-nparams Gr1 N,
256+
std.nth N Args (app [global Gr| _]).
257+
258+
pred extract_wrapped i:indt-decl, o:gref.
259+
extract_wrapped In Out :-
260+
extract_from_record_decl (extract_from_rtty xtr_fst_op) In Out.
261+
262+
pred extract_subject i:indt-decl, o:gref.
263+
extract_subject In Out :-
264+
extract_from_record_decl (extract_from_rtty xtr_snd_op) In Out.
265+
266+
pred wrapper_mixin_aux i:gref, o:gref, o:gref.
267+
wrapper_mixin_aux XX Gr1 Gr2 :-
268+
XX = (indt I),
269+
coq.env.indt-decl I D,
270+
extract_subject D Gr1,
271+
extract_wrapped D Gr2.
272+
273+
%%% end auxiliary code for wrapper-mixin
274+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275+
229276
pred declare-mixin-or-factory i:list prop, i:list constant, i:list term, i:term,
230277
i:term, i:record-decl, i:list-w-params factoryname, i:id, i:asset.
231278
declare-mixin-or-factory MixinSrcClauses SectionCanonicalInstance
@@ -262,6 +309,12 @@ declare-mixin-or-factory MixinSrcClauses SectionCanonicalInstance
262309

263310
% TODO: should this be in the Exports module?
264311

312+
% if the wrapper option is on, build the wrapper clause
313+
if (get-option "wrapper" tt)
314+
((wrapper_mixin_aux (indt R) NSbj WMxn),
315+
(WrapperClauses = [wrapper-mixin (indt R) NSbj WMxn]))
316+
(WrapperClauses = []),
317+
265318
if-verbose (coq.say {header} "declare notation Build"),
266319

267320
GRDepsClauses => phant.of-gref ff GRK [] PhGRK,
@@ -278,7 +331,7 @@ declare-mixin-or-factory MixinSrcClauses SectionCanonicalInstance
278331
if-verbose (coq.say {header} "start module Exports"),
279332

280333
log.coq.env.begin-module "Exports" none,
281-
std.flatten [Clauses, GRDepsClauses, [
334+
std.flatten [Clauses, GRDepsClauses, WrapperClauses, [
282335
factory-constructor (indt R) GRK,
283336
factory-nparams (indt R) NParams,
284337
factory-builder-nparams BuildConst NParams,

0 commit comments

Comments
 (0)