@@ -105,10 +105,14 @@ declare Module BSkel Sort :- std.do! [
105105 %]),
106106
107107 if-verbose (coq.say {header} "making coercion from type to target"),
108- synthesis.infer-coercion-tgt MLwP CoeClass,
109- if-arg-sort (private.declare-sort-coercion CoeClass Structure
110- (global (const ArgSortCst))),
111- private.declare-sort-coercion CoeClass Structure SortProjection,
108+ if (synthesis.infer-coercion-tgt MLwP CoeClass)
109+ (if-arg-sort (private.declare-sort-coercion CoeClass Structure
110+ (global (const ArgSortCst))),
111+ private.declare-sort-coercion CoeClass Structure SortProjection)
112+ (if-arg-sort (private.declare-sort-coercion-elpi (global Structure) (global (const ArgSortCst))),
113+ private.declare-sort-coercion-elpi (global Structure) SortProjection),
114+
115+ private.declare-reverse-coercion-elpi Structure,
112116
113117 if-verbose (coq.say {header} "exporting unification hints"),
114118 ClassAlias => Factories => GRDepsClauses =>
@@ -137,24 +141,26 @@ declare Module BSkel Sort :- std.do! [
137141
138142 log.coq.env.import-module "Exports" Exports,
139143
140- if-verbose (coq.say {header} "declaring on_ abbreviation"),
144+ if (var CoeClass)
145+ (if-verbose (coq.say {header} "could not declare the `on_`, `copy` and `on` abbreviations because the target of sort is not a coercion class"))
146+ (if-verbose (coq.say {header} "declaring on_ abbreviation"),
141147
142- private.mk-infer-key CoeClass ClassProjection NilwP (global Structure) PhClass,
148+ private.mk-infer-key CoeClass ClassProjection NilwP (global Structure) PhClass,
143149
144- phant.add-abbreviation "on_" PhClass _ ClassOfAbbrev,
145- (pi c\ coq.notation.abbreviation ClassOfAbbrev [c] (ClassOfAbbrev_ c)),
150+ phant.add-abbreviation "on_" PhClass _ ClassOfAbbrev,
151+ (pi c\ coq.notation.abbreviation ClassOfAbbrev [c] (ClassOfAbbrev_ c)),
146152
147- if-verbose (coq.say {header} "declaring `copy` abbreviation"),
153+ if-verbose (coq.say {header} "declaring `copy` abbreviation"),
148154
149- coq.mk-app (global ClassName) {params->holes NilwP} AppClassHoles,
150- @global! => log.coq.notation.add-abbreviation "copy" 2
151- {{fun T C => (lp:(ClassOfAbbrev_ C) : (lp:AppClassHoles T)) }} tt _,
155+ coq.mk-app (global ClassName) {params->holes NilwP} AppClassHoles,
156+ @global! => log.coq.notation.add-abbreviation "copy" 2
157+ {{fun T C => (lp:(ClassOfAbbrev_ C) : (lp:AppClassHoles T)) }} tt _,
152158
153- if-verbose (coq.say {header} "declaring on abbreviation"),
159+ if-verbose (coq.say {header} "declaring on abbreviation"),
154160
155- @global! => log.coq.notation.add-abbreviation "on" 1
156- {{fun T => (lp:{{ ClassOfAbbrev_ {{_}} }} : (lp:AppClassHoles T)) }} tt
157- _OnAbbrev,
161+ @global! => log.coq.notation.add-abbreviation "on" 1
162+ {{fun T => (lp:{{ ClassOfAbbrev_ {{_}} }} : (lp:AppClassHoles T)) }} tt
163+ _OnAbbrev) ,
158164
159165 log.coq.env.end-module-name Module ModulePath,
160166
@@ -276,6 +282,47 @@ export-operations Structure ProjSort ProjClass MLwP EX1 EX2 MLToExport :- std.do
276282 std.map LMwPToExport w-params_1 MLToExport,
277283].
278284
285+ pred mk-sort-coercion-aux i:term, i:term, i:term, i:list term, o:prop.
286+ mk-sort-coercion-aux (prod _N _T Body) Structure P Args Clause :-
287+ Clause = (pi x\ C x),
288+ pi x\ mk-sort-coercion-aux (Body x) Structure P [x | Args] (C x).
289+
290+ mk-sort-coercion-aux _ Structure P Args Clause :-
291+ std.rev Args ArgsRev,
292+ Clause =
293+ (pi ctx v t e r argsAll w\ (coercion ctx v (app [Structure | ArgsRev]) e r :-
294+ coq.say "try sort coercion",
295+ std.append ArgsRev [v] argsAll,
296+ coq.mk-app P argsAll w,
297+ coq.say "find coercion from sort",
298+ coq.elaborate-skeleton w e r ok,
299+ coq.ltac.collect-goals r [] [],
300+ coq.say "sort coercion succeeds")).
301+
302+ pred mk-sort-coercion i:term, i:term, o:prop.
303+ mk-sort-coercion Structure P Clause :-
304+ std.assert-ok! (coq.typecheck Structure T) "anomaly: mk-sort-coercion",
305+ mk-sort-coercion-aux T Structure P [] Clause.
306+
307+ pred mk-reverse-coercion-aux i:term, i:term, i:term, i:list term, o:prop.
308+ mk-reverse-coercion-aux (prod _N _T Body) Structure G Args (pi x\ C x) :-
309+ pi x\ mk-reverse-coercion-aux (Body x) Structure G [x | Args] (C x).
310+
311+ mk-reverse-coercion-aux _ Structure G Args Clause :-
312+ std.rev Args ArgsRev,
313+ Clause =
314+ (pi ctx v t e r c argsAll w\ (coercion ctx v t (app [Structure | ArgsRev]) r :-
315+ std.append ArgsRev [v, c] argsAll,
316+ coq.mk-app G argsAll w,
317+ coq.elaborate-skeleton w e r ok,
318+ coq.ltac.collect-goals r [] [])).
319+
320+ pred mk-reverse-coercion i:gref, o:prop.
321+ mk-reverse-coercion Structure Clause :-
322+ coq.env.typeof Structure T,
323+ get-constructor Structure G,
324+ mk-reverse-coercion-aux T (global Structure) (global G) [] Clause.
325+
279326pred mk-coe-class-body
280327 i:factoryname, % From class
281328 i:factoryname, % To class
@@ -428,18 +475,23 @@ declare-unification-hints SortProj ClassProj CurrentClass NewJoins :- std.do! [
428475
429476% For each mixin we declare a field and apply the mixin to its dependencies
430477% (that are previously declared fields recorded via field-for-mixin)
431- pred synthesize-fields i:term, i:list (w-args mixinname), o:record-decl.
432- synthesize-fields _T [] end-record.
433- synthesize-fields T [triple M Args _|ML] (field _ Name MTy Fields) :- std.do! [
478+ % Keeps track of whether every field is in Prop
479+ pred synthesize-fields i:term, i:list (w-args mixinname), o:record-decl, o:bool.
480+ synthesize-fields _T [] end-record tt.
481+ synthesize-fields T [triple M Args V|ML] (field _ Name MTy Fields) B :- std.do! [
482+ if (coq.typecheck {mk-app (global M) {std.append Args [V]} } {{ Prop }} ok)
483+ (B = B2)
484+ (B = ff),
434485 Name is {gref->modname M 2 "_"} ^ "_mixin",
435486 if-verbose (coq.say {header} "typing class field" M),
436487 std.assert! (synthesis.infer-all-gref-deps Args T M MTy) "anomaly: a field type cannot be solved",
437- @pi-decl `m` MTy m\ mixin-src T M m => synthesize-fields T ML (Fields m)
488+ @pi-decl `m` MTy m\ mixin-src T M m => synthesize-fields T ML (Fields m) B2
438489].
439490
440491pred synthesize-fields.body i:list term, i:term, i:list (w-args mixinname), o:indt-decl.
441- synthesize-fields.body _Params T ML (record "axioms_" {{ Type }} "Class" FS) :-
442- synthesize-fields T ML FS.
492+ synthesize-fields.body _Params T ML (record "axioms_" Ty "Class" FS) :-
493+ synthesize-fields T ML FS B,
494+ if (B = tt) (Ty = {{ Prop }}) (Ty = {{ Type }}).
443495
444496pred mk-record+sort-field i:sort, i:name, i:term, i:(term -> record-decl), o:indt-decl.
445497pred mk-record+sort-field i:universe, i:name, i:term, i:(term -> record-decl), o:indt-decl.
@@ -495,6 +547,27 @@ declare-sort-coercion CoeClass StructureName (global Proj) :-
495547
496548 log.coq.coercion.declare (coercion Proj 0 StructureName CoeClass).
497549
550+ % Declares "sort" as a Coercion in elpi's coercion db Proj : Structurename >-> CoeClass.
551+ pred declare-sort-coercion-elpi i:term, i:term.
552+ declare-sort-coercion-elpi Structure Proj :-
553+
554+ if-verbose (coq.say {header} "declare sort coercion in elpi"),
555+
556+ %TODO: log.coq.coercion-elpi.declare
557+ mk-sort-coercion Structure Proj Clause,
558+ coq.elpi.accumulate _ "coercion.db" (clause _ _ Clause).
559+
560+ % Declares a reverse coercion for the sort projection in elpi's coercion db
561+ pred declare-reverse-coercion-elpi i:gref.
562+ declare-reverse-coercion-elpi Structure :-
563+
564+ if-verbose (coq.say {header} "declare reverse coercion in elpi"),
565+
566+ %TODO: log.coq.coercion-elpi.declare
567+ mk-reverse-coercion Structure Clause,
568+ coq.elpi.accumulate _ "coercion.db" (clause _ _ Clause).
569+
570+
498571pred if-class-already-exists-error i:id, i:list class, i:list mixinname.
499572if-class-already-exists-error _ [] _.
500573if-class-already-exists-error N [class _ S ML1wP|CS] ML2 :-
0 commit comments