Skip to content

Commit f5cc80a

Browse files
authored
Merge pull request #146 from math-comp/phant-params
inference of structures on paramters
2 parents 7b4463d + 7c65a67 commit f5cc80a

File tree

5 files changed

+78
-4
lines changed

5 files changed

+78
-4
lines changed

.github/workflows/main.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ jobs:
2727
opam:
2828
runs-on: ubuntu-latest
2929
strategy:
30+
fail-fast: false
3031
matrix:
3132
coq_version:
3233
- '8.11'

_CoqProject

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,5 +53,6 @@ tests/instance_params_no_type.v
5353
tests/test_CS_db_filtering.v
5454
tests/subtype.v
5555
tests/exports.v
56+
tests/infer.v
5657

5758
-R . HB

hb.elpi

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -82,17 +82,33 @@ under.do! Then LP :- Then (_\ std.do! LP) _.
8282

8383
%%%%% HB Utils %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
8484

85+
86+
% HACK: move to coq-elpi proper, remove when coq-elpi > 1.9.2
87+
type attmap attribute-type.
88+
8589
% runs P in a context where Coq #[attributes] are parsed
8690
pred with-attributes i:prop.
8791
with-attributes P :-
8892
attributes A,
93+
94+
% HACK: move to coq-elpi proper, remove when coq-elpi > 1.9.2
95+
(pi S L AS Prefix R R1 Map PS\
96+
parse-attributes.aux [attribute S (node L)|AS] Prefix R :-
97+
if (Prefix = "") (PS = S) (PS is Prefix ^ "." ^ S), supported-attribute (att PS attmap), !,
98+
parse-attributes.aux AS Prefix R1,
99+
(pi x\ supported-attribute (att x string) :- !) => parse-attributes.aux L "" Map,
100+
std.append R1 [get-option PS Map] R
101+
) =>
102+
89103
coq.parse-attributes A [
90104
att "verbose" bool,
91105
att "mathcomp" bool,
92106
att "mathcomp.axiom" string,
107+
att "infer" attmap,
93108
] Opts, !,
94109
Opts => P.
95110

111+
96112
pred if-verbose i:prop.
97113
if-verbose P :- get-option "verbose" tt, !, P.
98114
if-verbose _.
@@ -646,6 +662,7 @@ type mterm list term -> term -> list mixinname -> term -> mterm.
646662
% - [id] using [unify-arg]
647663
kind phant-arg type.
648664
type real-arg name -> phant-arg.
665+
type infer-type name -> phant-arg.
649666
type implicit-arg phant-arg.
650667
type unify-arg phant-arg.
651668

@@ -920,15 +937,18 @@ mk-phant-abbrev.term K F [] K F.
920937
mk-phant-abbrev.term K F [real-arg N|AL] K'' (fun N _ AbbrevFx) :- !,
921938
pi x\ mk-phant-abbrev.term K {mk-app F [x]} AL K' (AbbrevFx x),
922939
K'' is K' + 1.
940+
mk-phant-abbrev.term K F [infer-type N|AL] K'' (fun N _ AbbrevFx) :- !,
941+
pi x\ mk-phant-abbrev.term K {mk-app F [{{ lib:hb.Phant lp:x }}]} AL K' (AbbrevFx x),
942+
K'' is K' + 1.
923943
mk-phant-abbrev.term K F [implicit-arg|AL] K' FAbbrev :- !,
924944
mk-phant-abbrev.term K {mk-app F [_]} AL K' FAbbrev.
925945
mk-phant-abbrev.term K F [unify-arg|AL] K' FAbbrev :- !,
926946
mk-phant-abbrev.term K {mk-app F [{{lib:@hb.id _ _}}]} AL K' FAbbrev.
927947

928948
pred mk-phant-abbrev i:string, i:phant-term, o:constant, o:abbreviation.
929-
mk-phant-abbrev N (phant-term AL T) C Abbrev :- std.do! [
949+
mk-phant-abbrev N (phant-term AL T1) C Abbrev :- std.do! [
930950
NC is "phant_" ^ N,
931-
std.assert-ok! (coq.typecheck T TTy) "mk-phant-abbrev: T illtyped",
951+
std.assert-ok! (coq.elaborate-skeleton T1 TTy T) "mk-phant-abbrev: T illtyped",
932952
hb-add-const NC T TTy @transparent! C,
933953
mk-phant-abbrev.term 0 (global (const C)) AL NParams AbbrevT,
934954
@global! => coq.notation.add-abbreviation N NParams AbbrevT tt Abbrev,
@@ -1499,7 +1519,8 @@ synthesize-fields.body _Params T ML (record "axioms" {{ Type }} "Class" FS) :-
14991519
synthesize-fields T ML FS.
15001520

15011521
pred mk-record+sort-field i:name, i:term, i:(term -> record-decl), o:indt-decl.
1502-
mk-record+sort-field _ T F (record "type" {{ Type }} "Pack" (field _ "sort" T F)).
1522+
mk-record+sort-field _ T F (record RecordName {{ Type }} "Pack" (field _ "sort" T F)) :-
1523+
if (get-option "infer" _) (RecordName = "type_") (RecordName = "type").
15031524

15041525
pred mk-class-field i:classname, i:list term, i:term, i:list (w-args mixinname), o:record-decl.
15051526
mk-class-field ClassName Params T _ (field _ "class" (app [global ClassName|Args]) _\end-record) :-
@@ -1634,6 +1655,25 @@ pack-body ClassName PL T MLwA F :- std.do! [
16341655
under-mixins.then MLwA mk-fun (pack-body.mixins PL T BuildC PackS) F
16351656
].
16361657

1658+
pred declare-auto-infer-params-abbrev i:structure, i:list-w-params mixinname.
1659+
declare-auto-infer-params-abbrev GR MLwP :- get-option "infer" Map, !,
1660+
Map => mk-infer (global GR) MLwP PHT,
1661+
mk-phant-abbrev "type" PHT _ _.
1662+
declare-auto-infer-params-abbrev _ _.
1663+
1664+
pred mk-infer i:term, i:list-w-params mixinname, o:phant-term.
1665+
mk-infer T (w-params.nil _ _ _) (phant-term [] T).
1666+
mk-infer T (w-params.cons N Ty W) (phant-term [implicit-arg, infer-type N|A] R1) :-
1667+
coq.name->id N ID, (get-option ID "Type" ; get-option ID ""), !,
1668+
R1 = (fun N Ty n\ fun `ph` {{ lib:@hb.phant lp:n }} _\ R n),
1669+
@pi-decl N Ty n\
1670+
mk-infer {mk-app T [n]} (W n) (phant-term A (R n)).
1671+
mk-infer T (w-params.cons N Ty W) (phant-term [real-arg N|A] (fun N Ty R)) :-
1672+
coq.name->id N ID, not (get-option ID _), !,
1673+
@pi-decl N Ty x\ mk-infer {mk-app T [x]} (W x) (phant-term A (R x)).
1674+
mk-infer _ (w-params.cons N _ _) _ :- coq.name->id N ID, get-option ID Infer,
1675+
coq.error "Automatic inference of paramter" N "from" Infer "not supported".
1676+
16371677
% HB.structure Definition S P1 P2 := { T of F1 P1 T & F2 P1 (P2*P2) T }
16381678
% cons p1\ cons p2\ nil t\ [triple f1 [p1] t,triple f2 [p1, {{p1 * p2}}] t]
16391679
pred main-declare-structure i:string, i:list-w-params gref, i:bool.
@@ -1668,6 +1708,8 @@ main-declare-structure Module GRFSwP ClosureCheck :- std.do! [
16681708
ClassRequires = factory-requires (ClassName) NilwP,
16691709
ClassAlias = (factory-alias->gref ClassName ClassName),
16701710
CurrentClass = (class ClassName Structure MLwP),
1711+
1712+
declare-auto-infer-params-abbrev Structure MLwP,
16711713

16721714
if-verbose (coq.say "HB: declaring clone abbreviation"),
16731715

@@ -2213,4 +2255,4 @@ declare-mixin-or-factory Sort1 Fields GRFSwP Module TheType D TheParams :- std.d
22132255
export Exports,
22142256

22152257
declare-factory-abbrev Module FactAbbrev,
2216-
].
2258+
].

structures.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ Register Coq.Init.Datatypes.Some as hb.some.
1818
Register Coq.Init.Datatypes.pair as hb.pair.
1919
Register Coq.Init.Datatypes.prod as hb.prod.
2020
Register Coq.Init.Specif.sigT as hb.sigT.
21+
Register Coq.ssr.ssreflect.phant as hb.phant.
22+
Register Coq.ssr.ssreflect.Phant as hb.Phant.
2123
Definition indexed {T} (x : T) := x.
2224
Bind Scope type_scope with indexed.
2325
Register indexed as hb.indexed.

tests/infer.v

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
From HB Require Import structures.
2+
3+
HB.mixin Record foom T := {
4+
op : T -> T -> T
5+
}.
6+
7+
HB.structure Definition foo := { T of foom T }.
8+
9+
HB.instance Definition i := foom.Build nat plus.
10+
11+
HB.mixin Record barm (A : Type) (P : foo.type) (B: Type) (T : indexed Type) := {
12+
law : P -> T -> A -> B
13+
}.
14+
15+
#[infer(P)]
16+
HB.structure Definition bar A P B := { T of barm A P B T }.
17+
18+
Fail Check bar.type_ bool nat bool.
19+
Print bar.phant_type.
20+
Print bar.type.
21+
Check bar.type bool nat bool.
22+
23+
Fail #[infer(P = "whatever")]
24+
HB.structure Definition bar1 P := { T of barm bool P bool T & foom T }.
25+
26+
#[infer(P = "Type")]
27+
HB.structure Definition bar1 P := { T of barm bool P bool T & foom T }.
28+
Check bar1.type nat.

0 commit comments

Comments
 (0)