Skip to content

Commit 81cdb25

Browse files
committed
Fixes and cleanups
1 parent 17784b9 commit 81cdb25

23 files changed

+245
-249
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,3 @@ _minted-*
5858
*.vtc
5959

6060
*.dot
61-
*.json

Changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## Unreleased
44

55
- **Removed** the `#[primitive_class]` attribute, making it the default.
6+
- **New** `HB.saturate` to saturate instances w.r.t. the current hierarchy
67

78
## [1.6.0] - 2023-09-20
89

HB/common/database.elpi

Lines changed: 43 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* Hierarchy Builder: algebraic hierarchies made easy
22
This software is released under the terms of the MIT license */
33

4-
shorten coq.{ term->gref, term-is-gref?, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }.
4+
shorten coq.{ term->gref, subst-fun, safe-dest-app, mk-app, mk-eta, subst-prod }.
55

66
%%%%%%%%% HB database %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77

@@ -14,13 +14,6 @@ from_mixin (from _ X _) X.
1414
pred from_builder i:prop, o:term.
1515
from_builder (from _ _ X) (global X).
1616

17-
% for a given clause mixin-src with eventually a condition,
18-
% returns the type of the first argument
19-
pred mixin-src-w-cond_type i:prop, o:term.
20-
mixin-src-w-cond_type(mixin-src (global G) _ _ :- _) (global G).
21-
mixin-src-w-cond_type (mixin-src (app [T|_]) _ _ :- _) T.
22-
mixin-src-w-cond_type (pi x \ (C x)) T :- pi y \ mixin-src-w-cond_type (C y) T.
23-
2417
pred mixin-src_mixin i:prop, o:mixinname.
2518
mixin-src_mixin (mixin-src _ M _) M.
2619

@@ -146,16 +139,31 @@ undup-grefs L UL :- std.do! [
146139
coq.gref.set.elements S UL,
147140
].
148141

149-
% remove duplicates from a list of terms, but all the terms have to be global references
150-
pred undup-terms i:list term, o:list term.
151-
undup-terms L UL :- std.do! [
152-
std.map L coq.term->gref LG,
153-
undup-grefs LG ULG,
154-
std.map ULG (coq.env.global ) UL,
142+
pred undup-sorts i:list sort, o:list sort.
143+
undup-sorts L R :- std.do! [
144+
145+
if (std.mem L prop) (R1 = [prop]) (R1 = []),
146+
if (std.mem L sprop) (R2 = [sprop]) (R2 = []),
147+
if (std.mem L (typ _)) (R3 = [typ _]) (R3 = []),
148+
149+
std.flatten [R1, R2, R3] R,
155150
].
156151

152+
% also prunes cs-default
153+
pred undup-cs-patterns i:list cs-pattern, o:list cs-pattern.
154+
undup-cs-patterns L R :- std.do! [
155+
std.map-filter L (x\r\ x = cs-gref r) LGR,
156+
undup-grefs LGR ULGR,
157+
std.map ULGR (x\r\ r = cs-gref x) R1,
157158

159+
std.map-filter L (x\r\ x = cs-sort r) LS,
160+
undup-sorts LS ULS,
161+
std.map ULS (x\r\ r = cs-sort x) R2,
158162

163+
if (std.mem L cs-prod) (R3 = [cs-prod]) (R3 = []),
164+
165+
std.flatten [R1, R2, R3] R,
166+
].
159167

160168
% Mixins can be topologically sorted according to their dependencies
161169
pred toposort-mixins i:list (w-args mixinname), o:list (w-args mixinname).
@@ -220,10 +228,13 @@ pred findall-has-mixin-instance o:list prop.
220228
findall-has-mixin-instance CL :-
221229
std.findall (has-mixin-instance _ _ _) CL.
222230

231+
pred has-mixin-instance_key i:prop, o:cs-pattern.
232+
has-mixin-instance_key (has-mixin-instance P _ _) P.
233+
223234
pred findall-mixin-src i:term, o:list mixinname.
224235
findall-mixin-src T ML :-
225236
std.map {std.findall (mixin-src T M_ V_)} mixin-src_mixin ML.
226-
237+
227238
pred findall-local-canonical o:list constant.
228239
findall-local-canonical CL :-
229240
std.map {std.findall (local-canonical C_)} local-canonical-gref CL.
@@ -300,7 +311,6 @@ assert-good-coverage! MLSortedRev CNL :- std.do! [
300311
true
301312
].
302313

303-
304314
%%%%% Coq Database %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
305315

306316
% [get-structure-coercion S1 S2 F] finds the coecion F from the structure S1 to S2
@@ -359,72 +369,47 @@ mixin-src->has-mixin-instance (mixin-src (sort U) M I) (has-mixin-instance (cs-s
359369
% this auxiliary function iterates over the list of arguments of an application,
360370
% and create the necessary unify condition for each arguments
361371
% and at the end returns the mixin-src clause with all the conditions
362-
pred mk-src-aux
372+
pred mixin-instance-type->mixin-src.aux
363373
i:list term, % list of arguments
364374
i:term, % head of the original application
365375
i:mixinname, % name of mixin
366376
i:term, % instance body
367377
i:list prop, % Cond list
368378
o:prop.
369-
mk-src-aux [] T M I Cond (mixin-src T M I :- Cond).
370-
mk-src-aux [A|Args] T M I Cond (pi a \ C a) :-
379+
mixin-instance-type->mixin-src.aux [] T M I Cond (mixin-src T M I :- Cond).
380+
mixin-instance-type->mixin-src.aux [A|Args] T M I Cond (pi a \ C a) :-
371381
pi a \
372382
sigma Ta\
373383
coq.mk-app T [a] Ta,
374-
mk-src-aux Args Ta M I [coq.unify-eq A a ok|Cond] (C a).
384+
mixin-instance-type->mixin-src.aux Args Ta M I [coq.unify-eq A a ok|Cond] (C a).
375385

376386

377-
% transforms the has-mixin-instance clause arguments into a
378-
% mixin-src clause with eventuals conditions regarding its parameters
379-
pred mk-src
387+
% transforms the type of a mixin instance into a
388+
% mixin-src clause with eventual conditions regarding its parameters
389+
pred mixin-instance-type->mixin-src
380390
i:term, % type of the instance Ty
381391
i:mixinname, % name of mixin
382392
i:term, % instance body I of type Ty
383393
i:list prop, % Cond list
384394
o:prop.
385395

386-
mk-src (app [_|Args]) M I Cond C :-
387-
std.last Args Last,
388-
safe-dest-app Last Hd ArgsLast,
389-
mk-src-aux ArgsLast Hd M I Cond C.
396+
mixin-instance-type->mixin-src (app _ as F) M I Cond C :-
397+
factory? F (triple _ _ Subject),
398+
safe-dest-app Subject Hd Args,
399+
mixin-instance-type->mixin-src.aux Args Hd M I Cond C.
390400

391-
mk-src (prod N_ _ F) M I Cond (pi a \ C a) :-
401+
mixin-instance-type->mixin-src (prod N_ _ F) M I Cond (pi a \ C a) :-
392402
pi a\
393403
sigma Ia \
394404
coq.mk-app I [a] Ia,
395-
mk-src (F a) M Ia Cond (C a).
396-
397-
398-
% for a type T, create as many holes as there are foralls and returns that enriched type
399-
pred enrich-type i:term, o:term .
400-
enrich-type T ET :-
401-
coq.typecheck T TH ok,
402-
coq.count-prods TH N,
403-
if (N = 0) (ET = T) (coq.mk-app T {coq.mk-n-holes N} ET).
405+
mixin-instance-type->mixin-src (F a) M Ia Cond (C a).
404406

405-
% wrapper for mk-src so it can be called by a map on a list of clauses has-mixin-instance
406-
pred mk-src-map i:prop, o:prop.
407-
mk-src-map (has-mixin-instance _ M IHd) C :- std.do![
407+
pred has-mixin-instance->mixin-src i:prop, o:prop.
408+
has-mixin-instance->mixin-src (has-mixin-instance _ M IHd) C :- std.do![
408409
T = global IHd,
409410
coq.env.typeof IHd Ty,
410-
mk-src Ty M T [] C,
411-
].
412-
413-
pred cs-pattern->term i:cs-pattern, o:term.
414-
cs-pattern->term (cs-gref GR) (global GR).
415-
cs-pattern->term (cs-sort U) (sort U).
416-
417-
pred term->cs-pattern i:term, o:cs-pattern.
418-
term->cs-pattern (prod _ _ _) cs-prod.
419-
term->cs-pattern (sort U) (cs-sort U).
420-
term->cs-pattern T (cs-gref GR) :- term->gref T GR.
421-
term->cs-pattern T _ :- coq.error T "HB database: is not a valid canonical key".
422-
423-
pred cs-pattern->name i:cs-pattern, o:string.
424-
cs-pattern->name cs-prod "prod".
425-
cs-pattern->name (cs-sort _) "sort".
426-
cs-pattern->name cs-default "default".
427-
cs-pattern->name (cs-gref GR) Name :- gref->modname-label GR 1 "_" Name.
411+
mixin-instance-type->mixin-src Ty M T [] C,
412+
].
428413

429414
pred get-canonical-structures i:term, o:list structure.
430415
get-canonical-structures TyTrm StructL :- std.do! [

HB/common/stdpp.elpi

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,86 @@ coq.fold-map (primitive _ as C) A C A :- !.
251251
coq.fold-map (uvar M L as X) A W A1 :- var X, !, std.fold-map L A coq.fold-map L1 A1, coq.mk-app-uvar M L1 W.
252252
% when used in CHR rules
253253
coq.fold-map (uvar X L) A (uvar X L1) A1 :- std.fold-map L A coq.fold-map L1 A1.
254+
255+
pred cs-pattern->term i:cs-pattern, o:term.
256+
cs-pattern->term (cs-gref GR) T :- coq.env.global GR T.
257+
cs-pattern->term (cs-sort prop) (sort prop).
258+
cs-pattern->term (cs-sort sprop) (sort sprop).
259+
cs-pattern->term (cs-sort _) T :- coq.elaborate-skeleton {{ Type }} _ T ok.
260+
cs-pattern->term cs-prod T :- coq.elaborate-skeleton (prod `x` Ty_ x\ Bo_ x) _ T ok.
261+
262+
pred term->cs-pattern i:term, o:cs-pattern.
263+
term->cs-pattern (prod _ _ _) cs-prod.
264+
term->cs-pattern (sort U) (cs-sort U).
265+
term->cs-pattern T (cs-gref GR) :- coq.term->gref T GR.
266+
term->cs-pattern T _ :- coq.error T "HB database: is not a valid canonical key".
267+
268+
pred cs-pattern->name i:cs-pattern, o:string.
269+
cs-pattern->name cs-prod "prod".
270+
cs-pattern->name (cs-sort _) "sort".
271+
cs-pattern->name cs-default "default".
272+
cs-pattern->name (cs-gref GR) Name :- gref->modname-label GR 1 "_" Name.
273+
274+
% ---------------------------------------------------------------------
275+
% kit for closing a term by abstracting evars with lambdas
276+
% we use constraints to attach to holes a number
277+
% and replace them by a special node, to later be bound
278+
% via a lambda
279+
280+
namespace abstract-holes {
281+
282+
% we add a new constructor to terms to represent terms to be abstracted
283+
type abs int -> term.
284+
285+
% bind back abstracted subterms
286+
pred bind i:int, i:int, i:term, o:term.
287+
bind I M T T1 :- M > I, !,
288+
T1 = {{ fun x => lp:(B x) }},
289+
N is I + 1,
290+
pi x\ % we allocate the fresh symbol for (abs M)
291+
(copy (abs N) x :- !) => % we schedule the replacement (abs M) -> x
292+
bind N M T (B x).
293+
bind M M T T1 :- copy T T1. % we perform all the replacements
294+
295+
% for a term with M holes, returns a term with M variables to fill these holes
296+
% the clause see is only generated for a term if it hasn't been seen before
297+
% the term might need to be typechecked first or main generates extra holes for the
298+
% type of the parameters
299+
pred main i:term, o:term.
300+
main T1 T3 :- std.do! [
301+
% we put (abs N) in place of each occurrence of the same hole
302+
(pi T Ty N N' M \ fold-map T N (abs M) M :- var T, not (seen? T _), !, coq.typecheck T Ty ok, fold-map Ty N _ N', M is N' + 1, seen! T M) =>
303+
(pi T N M \ fold-map T N (abs M) N :- var T, seen? T M, !) =>
304+
fold-map T1 0 T2 M,
305+
% we abstract M holes (M abs nodes)
306+
bind 0 M T2 T3,
307+
% cleanup constraint store
308+
purge-seen!,
309+
].
310+
311+
% all constraints are also on _ so that they share
312+
% a variable with the constraint to purge the store
313+
314+
% we query if the hole was seen before, and if so
315+
% we fetch its number
316+
pred seen? i:term, o:int.
317+
seen? X Y :- declare_constraint (seen? X Y) [X,_].
318+
319+
% we declare it is now seen and label it with a number
320+
pred seen! i:term, i:int.
321+
seen! X Y :- declare_constraint (seen! X Y) [X,_].
322+
323+
% to empty the store
324+
pred purge-seen!.
325+
purge-seen! :- declare_constraint purge-seen! [_].
326+
327+
constraint seen? seen! purge-seen! {
328+
% a succesful query, give the label back via M
329+
rule (seen! X N) \ (seen? X M) <=> (M = N).
330+
% an unsuccesful query
331+
rule \ (seen? X _) <=> false.
332+
333+
rule purge-seen! \ (seen! _ _).
334+
rule \ purge-seen!.
335+
}
336+
}

HB/common/utils.elpi

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -375,3 +375,10 @@ prod-last X X :- !.
375375
pred prod-last-gref i:term, o:gref.
376376
prod-last-gref (prod N S X) GR :- !, @pi-decl N S x\ prod-last-gref (X x) GR.
377377
prod-last-gref X GR :- coq.term->gref X GR.
378+
379+
% saturate a type constructor with holes
380+
pred saturate-type-constructor i:term, o:term .
381+
saturate-type-constructor T ET :-
382+
coq.typecheck T TH ok,
383+
coq.count-prods TH N,
384+
coq.mk-app T {coq.mk-n-holes N} ET.

HB/context.elpi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ postulate-mixin TheType (triple M Ps T) (triple CL MSL MLwP) (triple OutCL [MC|M
7373

7474
MC = mixin-src T M (global (const C)),
7575
MC => get-option "local" tt =>
76-
instance.declare-all-generic-type TheType {findall-classes-for [M]} NewCSL,
76+
instance.declare-all TheType {findall-classes-for [M]} NewCSL,
7777
std.map NewCSL snd NewCL,
7878
std.append CL NewCL OutCL
7979
].

0 commit comments

Comments
 (0)