File: pack.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 (73 lines) | stat: -rw-r--r-- 3,566 bytes parent folder | download | duplicates (2)
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

/*        Hierarchy Builder: algebraic hierarchies made easy
    This software is released under the terms of the MIT license              */

namespace pack {

pred main i:term, i:list argument, o:term.
main Ty Args Instance :- std.do! [
  std.assert! (not(var Ty)) "HB.pack: the structure to pack cannot be unknown, use HB.pack_for",
  std.assert! (coq.safe-dest-app {unwind {whd Ty []}} (global Structure) Params) "HB.pack: not a structure",
  std.assert! (class-def (class Class Structure _)) "HB.pack: not a structure",
  std.assert! (Args = [trm TSkel|FactoriesSkel]) "HB.pack: not enough arguments",

  get-constructor Class KC,
  get-constructor Structure KS,

  std.assert-ok! (d\
    (coq.elaborate-ty-skeleton TSkel _ T d, d = ok) ;
     coq.elaborate-skeleton    TSkel _ T d
  ) "HB.pack: not a well typed key",

  private.elab-factories FactoriesSkel T Factories,

  if (var T) (coq.error "HB.pack: you must pass a type or at least one factory") true,

  if2 (T = app[global (const SortProj)|ProjParams], structure-key SortProj ClassProj _)
        (AllFactories = [app[global (const ClassProj)|ProjParams] | Factories], Tkey = T) % already existing class on T
      (def T _ _ Tkey) % we unfold letins if we can, they may hide constants with CS instances
        (AllFactories = Factories)
      (AllFactories = Factories, Tkey = T), % it's a factory, won't add anything

  private.synth-instance Params KC KS T Tkey AllFactories Instance,

].

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

namespace private {

pred synth-instance i:list term, i:gref, i:gref, i:term, i:term, i:list term, o:term.
synth-instance Params KC KS T Tkey [Factory|Factories] Instance :-
  synthesis.under-new-mixin-src-from-factory.do! Tkey Factory (_\
    synth-instance Params KC KS T Tkey Factories Instance).
synth-instance Params KC KS T Tkey [] Instance :- coq.safe-dest-app Tkey (global _) _, !,
  synthesis.under-local-canonical-mixins-of.do! Tkey [
    std.assert-ok! (synthesis.infer-all-args-let Params Tkey KC ClassInstance) "HB.pack: cannot infer the instance",
    std.append Params [T, ClassInstance] InstanceArgs,
      Instance = app[global KS | InstanceArgs]
].
synth-instance Params KC KS T Tkey [] Instance :- std.do! [
  std.assert-ok! (synthesis.infer-all-args-let Params Tkey KC ClassInstance) "HB.pack: cannot infer the instance",
  std.append Params [T, ClassInstance] InstanceArgs,
    Instance = app[global KS | InstanceArgs]
].

pred elab-factories i:list argument, i:term, o:list term.
elab-factories [] _ [].
elab-factories [trm FactorySkel|More] T [Factory|Factories] :-
  std.assert-ok! (coq.elaborate-skeleton FactorySkel FTy MaybeFactory) "HB.pack: illtyped factory",
  if2 (factory? {unwind {whd FTy []}} (triple _ _ T1)) % a factory
        (Factory = MaybeFactory)
      (coq.safe-dest-app {unwind {whd FTy []}}  (global GR) _, structure-key SortP ClassP GR) % a structure instance
        (coq.mk-n-holes {structure-nparams GR} Params,
         std.append Params [MaybeFactory] ParamsF,
         coq.mk-app (global (const SortP)) ParamsF T1,
         coq.mk-app (global (const ClassP)) ParamsF Factory)
      (coq.error "HB: argument" {coq.term->string MaybeFactory} "is not a factory, it has type:" {coq.term->string FTy}),
  std.assert-ok! (coq.unify-eq T T1) "HB.pack: factory for the wrong type",
  elab-factories More T Factories.

}}