Skip to content

Commit 6e41414

Browse files
committed
wip
1 parent 2a18376 commit 6e41414

File tree

3 files changed

+109
-36
lines changed

3 files changed

+109
-36
lines changed

hb.elpi

Lines changed: 102 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,10 @@ from_builder (from _ _ X) (global X).
371371
pred mixin-src_mixin i:prop, o:mixinname.
372372
mixin-src_mixin (mixin-src _ M _) M.
373373

374+
pred mixin-src_src i:prop, o:term.
375+
mixin-src_src (mixin-src _ _ S) S.
376+
377+
374378
pred extract-builder i:prop, o:builder.
375379
extract-builder (builder-decl B) B.
376380

@@ -533,10 +537,13 @@ get-structure-coercion (global S) (global T) (global F) :-
533537
coq.coercion.db-for (grefclass S) (grefclass T) L,
534538
if (L = [pr F _]) true (coq.error "No one step coercion from" S "to" T).
535539

540+
% TODO
536541
pred get-structure-sort-projection i:structure, o:term.
537-
get-structure-sort-projection (global (indt S)) (global (const P)) :-
542+
get-structure-sort-projection T Proj :-
543+
safe-dest-app T (global (indt S)) Params,
538544
coq.CS.canonical-projections S L,
539-
if (L = [some P, _]) true (coq.error "No canonical sort projection for" S).
545+
if (L = [some P, _]) true (coq.error "No canonical sort projection for" S),
546+
mk-app (global (const P)) Params Proj.
540547

541548
pred get-structure-class-projection i:structure, o:term.
542549
get-structure-class-projection (global (indt S)) (global (const P)) :-
@@ -650,8 +657,8 @@ phant-fun-real N T F Res :- !, phant-fun (real-arg N) T F Res.
650657
% N is ignored
651658
pred phant-fun-unify i:term, i:term, i:term, i:phant-term, o:phant-term.
652659
phant-fun-unify Msg X1 X2 (phant-term AL F) (phant-term [unify-arg|AL] UF) :-
653-
std.assert-ok! (coq.typecheck X1 T1) "mk-phant-abbrev: X1 illtyped",
654-
std.assert-ok! (coq.typecheck X2 T2) "mk-phant-abbrev: X2 illtyped",
660+
std.assert-ok! (coq.typecheck X1 T1) "phant-fun-unify: X1 illtyped",
661+
std.assert-ok! (coq.typecheck X2 T2) "phant-fun-unify: X2 illtyped",
655662
UF = {{fun unif_arbitrary : lib:hb.unify lp:T1 lp:T2 lp:X1 lp:X2 lp:Msg => lp:F}}.
656663

657664
% [phant-fun-implicit N Ty PF PUF] states that PUF is a phant-term
@@ -663,8 +670,9 @@ phant-fun-implicit N Ty PF (phant-term [implicit-arg|AL] (fun N Ty F)) :- !,
663670
pred phant-fun-unify-mixin i:term, i:name, i:term, i:(term -> phant-term), o:phant-term.
664671
phant-fun-unify-mixin T N Ty PF Out :- !, std.do! [
665672
safe-dest-app Ty (global M) _,
666-
mixin-src T M Mstr,
667-
(@pi-decl `m` Ty m\ phant-fun-unify {{lib:hb.nomsg}} m Mstr (PF m) (PFM m)),
673+
Msg is "phant-fun-unify-mixin: No mixin-src on " ^ {coq.term->string T},
674+
std.assert! (mixin-src T M Msrc) Msg,
675+
(@pi-decl `m` Ty m\ phant-fun-unify {{lib:hb.nomsg}} m Msrc (PF m) (PFM m)),
668676
phant-fun-implicit N Ty PFM Out
669677
].
670678

@@ -865,7 +873,7 @@ find-max-classes [M|Mixins] [C|Classes] :-
865873
std.filter Mixins (x\ not (std.mem! ML x)) Mixins',
866874
find-max-classes Mixins' Classes
867875
].
868-
find-max-classes [M|_] _ :- coq.error "cannot find a class containing mixin" M.
876+
find-max-classes [M|_] _ :- coq.error "HB: cannot find a class containing mixin" M.
869877

870878
pred under-mixins.then i:list (w-args mixinname),
871879
i:(name -> term -> (term -> A) -> A -> prop),
@@ -875,7 +883,7 @@ under-mixins.then [triple M Args T|ML] Mixin Pred Out :- std.do! [
875883
mgref->term Args T M MTy,
876884
(@pi-decl `m` MTy m\ mixin-src T M m =>
877885
under-mixins.then ML Mixin Pred (Body m)),
878-
Mixin `m` MTy Body Out
886+
Mixin `m` MTy Body Out,
879887
].
880888

881889
% [mk-mixin-fun.then MLwP Pred F] states that F has shape
@@ -966,25 +974,28 @@ pred mk-phant-term.mixins i:term, i:classname, i:phant-term,
966974
i:list term, i:name, i:term, i:(term -> list (w-args mixinname)), o:phant-term.
967975
mk-phant-term.mixins T CN PF Params N Ty MLwA Out :- std.do! [
968976
class-def (class CN SI _),
977+
mk-app SI Params SIParams,
969978
NoMsg = {{lib:hb.nomsg}},
970-
(@pi-decl N Ty t\ sigma SK KC ML\ std.do! [
979+
coq.name-suffix N "local" Nlocal,
980+
(@pi-decl Nlocal Ty t\ sigma SK KC ML\ std.do! [
971981
std.map (MLwA t) triple_1 ML,
972982
std.append Params [T] ParamsT,
973983
SKPT = app [global {get-constructor SI} | ParamsT],
974984
ClassTy = app [global CN | ParamsT],
975-
(@pi-decl `s` SI s\ @pi-decl `c` ClassTy c\ sigma PF2\ std.do![
976-
under-mixins.then (MLwA t) (phant-fun-unify-mixin T)
977-
(x\ sigma KC KCM\ std.do![
978-
get-constructor (global CN) KC,
979-
mgref->term Params t KC KCM,
980-
phant-fun-unify NoMsg KCM c PF x
981-
]) PF2,
985+
(@pi-decl `s` SIParams s\ @pi-decl `c` ClassTy c\ sigma PF2\ std.do![
986+
under-mixins.then (MLwA t) (phant-fun-unify-mixin T) (mk-phant-term.mixins.aux t Params c CN PF) PF2,
982987
phant-fun-unify NoMsg s {mk-app SKPT [c]} PF2 (PFU t s c)])
983988
]),
984-
Out = {phant-fun-struct T `s` SI s\
989+
Out = {phant-fun-struct T `s` SIParams s\
985990
{phant-fun-implicit `c` ClassTy (PFU T s)}}
986991
].
987992

993+
mk-phant-term.mixins.aux T Params C CN PF X :- std.do![
994+
get-constructor (global CN) KC,
995+
mgref->term Params T KC KCM,
996+
phant-fun-unify {{lib:hb.nomsg}} KCM C PF X,
997+
].
998+
988999
pred mk-phant-term.class i:term, i:classname, i:phant-term, o:phant-term.
9891000
mk-phant-term.class T CN PF CPF :- !, std.do! [
9901001
class-def (class CN _ CMLwP),
@@ -1008,11 +1019,63 @@ mk-phant-term F PhBody:- !, std.do! [
10081019
% toposort-mixins ML MLSorted,
10091020
MLwP = MLwPSorted, % Assumes we give them already sorted in dep order.
10101021
std.rev {list-w-params_list MLwPSorted} MLSortedRev,
1011-
find-max-classes MLSortedRev CNL, % TODO: filter out mixins tagged with phant-mixin-real
1022+
1023+
% phant-mixin-real is used to tag mixins which are passed as arguments
1024+
std.filter MLSortedRev (m\not(phant-mixin-real m)) MLSortedRevFiltered,
1025+
find-max-classes MLSortedRevFiltered CNL,
1026+
assert-good-coverage! MLSortedRevFiltered CNL,
1027+
10121028
w-params.then MLwP phant-fun-real phant-fun-real
10131029
(mk-phant-term.classes EtaF CNL) PhBody,
10141030
].
10151031

1032+
pred classname->mixins i:classname, o:list-w-params mixinname.
1033+
classname->mixins CN MLwP :- class-def (class CN _ MLwP).
1034+
1035+
pred class-coverage i:list classname, o:coq.gref.set.
1036+
class-coverage CNL CSet :-
1037+
std.map CNL classname->mixins CMLLwP,
1038+
std.map CMLLwP list-w-params_list CMLL,
1039+
coq.gref.list->set {std.flatten CMLL} CSet.
1040+
1041+
pred coq.gref.list->set i:list mixinname, o:coq.gref.set.
1042+
coq.gref.list->set L S :-
1043+
std.fold L {coq.gref.set.empty} coq.gref.set.add S.
1044+
1045+
pred assert-good-coverage! i:list mixinname, i:list classname.
1046+
assert-good-coverage! MLSortedRev CNL :- std.do! [
1047+
coq.gref.list->set MLSortedRev MLSet,
1048+
class-coverage CNL CMLSet,
1049+
if (not(coq.gref.set.equal MLSet CMLSet))
1050+
(coq.gref.set.diff CMLSet MLSet Extra,
1051+
coq.error "I could not find classes covering exactly mixins:"
1052+
{std.any->string MLSortedRev}
1053+
"In particular the covering" CNL "also includes mixins:"
1054+
{coq.gref.set.elements Extra}
1055+
"This should never happen, please report a bug.")
1056+
true
1057+
].
1058+
1059+
pred if-coverage-not-good-error i:list mixinname.
1060+
if-coverage-not-good-error ML :-
1061+
coq.gref.list->set ML MS,
1062+
std.forall ML (if-coverage-not-good-error.one MS).
1063+
1064+
pred if-coverage-not-good-error.one i:coq.gref.set, i:mixinname.
1065+
if-coverage-not-good-error.one MS M :- mixin-first-class M C, !,
1066+
class-coverage [C] CMS,
1067+
if (coq.gref.set.subset CMS MS)
1068+
true
1069+
(coq.gref.set.elements {coq.gref.set.remove M CMS} MissinFromCurrent,
1070+
coq.error "HB: the first structure declared in this hierarchy containing" {nice-gref->string M} "is" {nice-gref->string C}
1071+
"which also contains" {std.map MissinFromCurrent nice-gref->string} "."
1072+
"\nThe are two ways to fix this problem:"
1073+
"1) change the current structure to contain" {std.map MissinFromCurrent nice-gref->string} "as well;"
1074+
"2) amend the hierarchy by declaring a structure before" {nice-gref->string C}
1075+
"which contains at most" {std.map {coq.gref.set.elements {coq.gref.set.inter CMS MS}} nice-gref->string}).
1076+
if-coverage-not-good-error.one _ _. % new class is the first covering M
1077+
1078+
10161079
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10171080
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
10181081
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1053,7 +1116,7 @@ declare-instances T [class Class Struct MLwP|Rest] :-
10531116
coq.gref->id TGR TID,
10541117
Name is TID ^ "_is_a_" ^ {term->modname Struct},
10551118

1056-
if-verbose (coq.say "HB: declare canonical instance" Name),
1119+
if-verbose (coq.say "HB: declare canonical structure instance" Name),
10571120

10581121
get-constructor Struct KS,
10591122
mk-app (global KS) {std.append Params [T, KCApp]} S,
@@ -1574,6 +1637,7 @@ main-declare-structure Module GRFSwP ClosureCheck :- std.do! [
15741637
true,
15751638

15761639
if-class-already-exists-error Module {findall-classes} ML,
1640+
if-coverage-not-good-error ML,
15771641

15781642
% TODO: check we never define the superclass of an exising class
15791643

@@ -1687,8 +1751,8 @@ main-end-declare-builders :- std.do! [
16871751
export Exports,
16881752
].
16891753

1690-
pred add-mixin i:term, i:factoryname, i:mixinname, i:term, o:list prop.
1691-
add-mixin T FGR MissinMixin Bo [MixinSrcCl, BuiderDeclCl] :-
1754+
pred add-mixin i:term, i:factoryname, i:bool, i:mixinname, i:term, o:list prop.
1755+
add-mixin T FGR MakeCanon MissinMixin Bo [MixinSrcCl, BuiderDeclCl] :-
16921756
MixinSrcCl = mixin-src T MixinName (global (const C)),
16931757
BuiderDeclCl = builder-decl (builder N FGR MixinName (const C)),
16941758
new_int N, % timestamp
@@ -1701,19 +1765,22 @@ add-mixin T FGR MissinMixin Bo [MixinSrcCl, BuiderDeclCl] :-
17011765

17021766
% If the mixin instance is alreaduy a constant there is no need to
17031767
% alias it.
1704-
if (Bo = global (const C)) true (
1705-
Name is {nice-gref->string FGR} ^"_to_" ^ {nice-gref->string MixinName},
1706-
if-verbose (coq.say "HB: declare" Name),
1707-
hb-add-const Name Bo Ty @transparent! C
1708-
).
1768+
if (Bo = global (const C)) true
1769+
(Name is {nice-gref->string FGR} ^"_to_" ^ {nice-gref->string MixinName} ^ "__" ^ {std.any->string {new_int}},
1770+
if-verbose (coq.say "HB: declare" Name),
1771+
hb-add-const Name Bo Ty @transparent! C),
1772+
if (MakeCanon = tt, whd (global (const C)) [] (global (indc _)) _)
1773+
(if-verbose (coq.say "HB: declare canonical mixin instance" C),
1774+
coq.CS.declare-instance (const C))
1775+
true.
17091776

17101777
pred mixin-for_mixin-builder i:prop, o:term.
17111778
mixin-for_mixin-builder (mixin-for _ _ B) B.
17121779

1713-
pred add-all-mixins i:term, i:factoryname, i:list mixinname, o:list prop.
1714-
add-all-mixins T FGR MissingMixins Clauses :- std.do! [
1780+
pred add-all-mixins i:term, i:factoryname, i:list mixinname, i:bool, o:list prop.
1781+
add-all-mixins T FGR MissingMixins MakeCanon Clauses :- std.do! [
17151782
std.map MissingMixins (assert!-mixin-for T) MBL,
1716-
std.map2 MissingMixins MBL (add-mixin T FGR) ClausesL,
1783+
std.map2 MissingMixins MBL (add-mixin T FGR MakeCanon) ClausesL,
17171784
std.flatten ClausesL Clauses,
17181785
].
17191786

@@ -1734,7 +1801,7 @@ declare-canonical-instances-from-factory-and-local-builders T F _TheFactory FGR
17341801
if-verbose (coq.say "HB: new mixins from"
17351802
{coq.term->string F} "on" {coq.term->string T} ":"
17361803
{std.map MissingMixins nice-gref->string}),
1737-
MixinSrcFromF => add-all-mixins T FGR MissingMixins Clauses,
1804+
MixinSrcFromF => add-all-mixins T FGR MissingMixins ff Clauses,
17381805
Clauses => declare-instances T {findall-classes}
17391806
].
17401807

@@ -1743,8 +1810,11 @@ declare-canonical-instances-from-factory-and-local-builders T F _TheFactory FGR
17431810
% on T
17441811
pred declare-canonical-instances-from-factory i:term, i:term.
17451812
declare-canonical-instances-from-factory T F :-
1813+
coq.typecheck F TyF ok,
1814+
target-gref TyF GRF,
17461815
under-canonical-mixins-of.do! T [
17471816
under-mixin-src-from-factory.do! T F [
1817+
add-all-mixins T GRF {list-w-params_list {factory-provides GRF}} tt _,
17481818
declare-instances T {findall-classes}
17491819
]
17501820
].
@@ -1999,9 +2069,9 @@ declare-mixin-or-factory Sort1 Fields0 GRFSwP Module TheType D TheParams :- std.
19992069

20002070
% HACK: work around section discharging unused stuff
20012071
if (D = asset-mixin) (Fields1 = Fields0, HackExtraPhantNo = 0)
2002-
(std.map MixinSrcClauses mixin-src_mixin MLHack,
2003-
std.map MLHack (mn\r\ r = global mn) TheHackCrap,
2072+
(std.map MixinSrcClauses mixin-src_src TheHackCrap,
20042073
HackExtraPhantNo is {std.length TheHackCrap} + {std.length TheParams},
2074+
coq.say "CRAP" {std.append TheParams TheHackCrap},
20052075
hack-section-discharge-unused [TheType|{std.append TheParams TheHackCrap}] Fields0 Fields1),
20062076

20072077
if-verbose (coq.say "HB: declare record axioms_"),

structures.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,5 @@ Notation "[find v1, .., vn | t1 ∼ t2 ] rest" :=
520520
Notation "[find v | t1 ∼ t2 | msg ] rest" :=
521521
(fun v (_ : unify t1 t2 (Some msg)) => rest) (at level 0, only parsing) :
522522
form_scope.
523+
524+
Global Open Scope string_scope.

tests/subtype.v

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ HB.mixin Record is_inhab T := { default : T }.
44
HB.structure Definition Inhab := { T of is_inhab T }.
55

66
HB.mixin Record is_nontrivial T := { twodiff : forall x : T, exists y : T, ~~ (x = y) }.
7+
8+
HB.structure Definition Nontrivial1 := { T of is_nontrivial T }.
9+
710
HB.structure Definition Nontrivial := { T of is_inhab T & is_nontrivial T }.
811

912

@@ -19,11 +22,9 @@ SubK : forall x Px, val (@Sub x Px) = x
1922

2023
HB.structure Definition SUB (T : Type) (P : pred T) := { S of is_SUB T P S }.
2124

22-
23-
2425
HB.structure Definition SubInhab T P := { sT of is_inhab T & is_SUB T P sT }.
2526

26-
HB.structure Definition SubNontrivial T P := { sT of is_nontrivial T & is_SUB T P sT }.
27+
HB.structure Definition SubNontrivial T P := { sT of is_nontrivial sT & is_SUB T P sT }.
2728

2829
HB.factory Record InhabForSub (T : Inhab.type) P (sT : indexed Type) of SubNontrivial T P sT := {}.
2930

@@ -32,4 +33,4 @@ HB.builders Context (T : Inhab.type) (P : pred T) sT of InhabForSub T P sT.
3233
Axiom xxx : P (default : T).
3334
HB.instance Definition SubInhabMix := is_inhab.Build sT (Sub (default : T) xxx).
3435

35-
#[verbose] HB.end.
36+
HB.end.

0 commit comments

Comments
 (0)