@@ -371,6 +371,10 @@ from_builder (from _ _ X) (global X).
371371pred mixin-src_mixin i:prop, o:mixinname.
372372mixin-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+
374378pred extract-builder i:prop, o:builder.
375379extract-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
536541pred 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
541548pred get-structure-class-projection i:structure, o:term.
542549get-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
651658pred phant-fun-unify i:term, i:term, i:term, i:phant-term, o:phant-term.
652659phant-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)) :- !,
663670pred phant-fun-unify-mixin i:term, i:name, i:term, i:(term -> phant-term), o:phant-term.
664671phant-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
870878pred 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.
967975mk-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+
988999pred mk-phant-term.class i:term, i:classname, i:phant-term, o:phant-term.
9891000mk-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
17101777pred mixin-for_mixin-builder i:prop, o:term.
17111778mixin-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
17441811pred declare-canonical-instances-from-factory i:term, i:term.
17451812declare-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_"),
0 commit comments