File: builders.elpi

package info (click to toggle)
coq-hierarchy-builder 1.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,988 kB
  • sloc: makefile: 109
file content (152 lines) | stat: -rw-r--r-- 6,230 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*        Hierarchy Builder: algebraic hierarchies made easy
    This software is released under the terms of the MIT license              */

namespace builders {

pred begin i:context-decl.
begin CtxSkel :- std.do! [
  std.assert!(coq.next-synterp-action (begin-module Name)) "synterp code did not open module",
  if-verbose (coq.say {header} "begin module for builders"),
  log.coq.env.begin-module Name none,

  builders.private.factory CtxSkel IDF GRF,

  % the Super module to access operations/axioms shadowed by the ones in the factory
  if-verbose (coq.say {header} "begin module Super"),
  log.coq.env.begin-module "Super" none,
  if (GRF = indt FRecord) (std.do! [
    std.forall {coq.env.projections FRecord}
      builders.private.declare-shadowed-constant,
  ]) true,
  if-verbose (coq.say {header} "ended module Super"),
  log.coq.env.end-module-name "Super" _,

  log.coq.env.begin-section Name,
  if-verbose (coq.say {header} "postulating factories"),
  builders.private.postulate-factories Name IDF CtxSkel,
].

}

% "end" is a keyword, be put it in the namespace by hand
pred builders.end.
builders.end :- std.do! [
  current-mode (builder-from _ _ _ ModName),

  log.coq.env.end-section-name ModName,

  findall-builders LFIL,

  std.fold LFIL [] builders.private.declare-1-builder Clauses,

  if (Clauses = [])
     (coq.error "No builders to declare, did you forget HB.instance?")
     true,

  std.findall (abbrev-to-export F_ N_ A_) ExportClauses,
  coq.env.current-path CurModPath,
  std.filter ExportClauses (export.private.abbrev-in-module CurModPath) ExportClausesFiltered,

  % TODO: Do we need this module?
  std.assert!(coq.next-synterp-action (begin-module Name)) "synterp code did not open module",
  log.coq.env.begin-module Name none,

  acc-clauses current Clauses,
  acc-clauses current ExportClausesFiltered,
  
  % Clauses => ExportClausesFiltered => current-mode no-builder =>
  %   instance.declare-factory-sort-factory GR,

  log.coq.env.end-module-name Name Exports,
  log.coq.env.end-module-name ModName _,
  export.module {calc (ModName ^ "." ^ Name)} Exports,


].

/* ------------------------------------------------------------------------- */
/* ----------------------------- private code ------------------------------ */
/* ------------------------------------------------------------------------- */

pred factory.cdecl->w-mixins i:context-decl, o:w-mixins context-decl.

namespace builders.private {

% [declare-1-builder (builder _ F M B) From MoreFrom] Given B of type FB, it
% declares all the new builders F to M via B.
% From holds the (from F Mi Bi) new clauses during folding.
pred declare-1-builder i:builder, i:list prop, o:list prop.
declare-1-builder (builder _ SrcFactory TgtMixin _) FromClauses FromClauses :- (FromClauses => from SrcFactory TgtMixin _), !,
  if-verbose (coq.say {header} "skipping duplicate builder from"
    {nice-gref->string SrcFactory} "to" {nice-gref->string TgtMixin}).
declare-1-builder (builder _ SrcFactory TgtMixin B) FromClauses [from SrcFactory TgtMixin B|FromClauses] :-
  if-verbose (coq.say {header} "declare builder from"
    {nice-gref->string SrcFactory} "to" {nice-gref->string TgtMixin}).

% We add breviations for all constants what will be shadowed by projections
% if the factory.
pred declare-shadowed-constant i:option constant.
declare-shadowed-constant none.
declare-shadowed-constant (some C) :-
  coq.gref->id (const C) Id,
  std.forall {coq.locate-all Id} (declare-shadowed-located Id).

pred declare-shadowed-located i:string, i:located.
declare-shadowed-located Id (loc-gref GR) :-
  @global! => log.coq.notation.add-abbreviation Id 0 (global GR) ff _.
declare-shadowed-located Id (loc-abbreviation Abbrev) :-
  coq.notation.abbreviation-body Abbrev NArgs T,
  @global! => log.coq.notation.add-abbreviation Id NArgs T ff _.

pred postulate-factory-abbrev i:term, i:list term, i:id, i:factoryname, o:term.
postulate-factory-abbrev TheType Params Name Falias TheFactory :- std.do! [
  std.assert-ok! (factory-alias->gref Falias F) "HB",
  phant-abbrev F _ Fabv,
  coq.notation.abbreviation Fabv {std.append Params [TheType]} Package,
  Msg is "Unable to declare factory " ^ Name,
  std.assert-ok! (coq.typecheck-ty Package _) Msg,
  log.coq.env.add-section-variable-noimplicits Name Package C,
  TheFactory = global (const C),
].

% Only record fields can be exported as operations.
pred define-factory-operations i:term, i:list term, i:term, i:gref.
define-factory-operations TheType Params TheFactory (indt I) :- !,
  coq.env.indt I _ NIParams _ _ _ _,
  NHoles is NIParams - 1 - {std.length Params},
  coq.env.projections I PL,
  std.forall PL (define-factory-operation TheType Params TheFactory NHoles).
define-factory-operations _ _ _ _.

pred define-factory-operation i:term, i:list term, i:term, i:int, i:option constant.
define-factory-operation _ _ _ _ none.
define-factory-operation TheType Params TheFactory NHoles (some P) :-
  coq.mk-n-holes NHoles Holes,
  std.append Holes [TheFactory] Holes_Factory,
  std.append Params [TheType|Holes_Factory] Args,
  T = app[global (const P)|Args],
  std.assert-ok! (coq.typecheck T _) "Illtyped applied factory operation",
  coq.gref->id (const P) Name,
  @local! => log.coq.notation.add-abbreviation Name 0 T ff _.

pred factory i:context-decl, o:string, o:gref.
factory (context-item IDF _ T _ _\ context-end) IDF GR :- !,
  coq.safe-dest-app T (global GR) _.
factory (context-item _ _ _ _ R) IDF GR :- !, pi x\ factory (R x) IDF GR.
factory _ _ _ :- !, coq.error "the last context item is not a factory".

pred postulate-factories i:id, i:string, i:context-decl.
postulate-factories ModName IDF CDecl :- std.do! [
  factory.cdecl->w-mixins CDecl (pr FLwP _),
  context.declare.params-key FLwP ParamsSection FKey FLwA,
  std.assert! (FLwA = [triple GRF _ _])
    "HB: cannot declare builders for more than one factory at a time",
  gref-deps GRF DepswPRaw,
  context.declare.mixins FKey ParamsSection DepswPRaw _ _ _,
  std.map ParamsSection triple_2 FParams,
  postulate-factory-abbrev FKey FParams IDF GRF TheFactory,
  define-factory-operations FKey FParams TheFactory GRF,
  acc-clause current (current-mode (builder-from FKey TheFactory GRF ModName)),
].

}