-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathprodutils.ml
135 lines (114 loc) · 2.5 KB
/
produtils.ml
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
(*
* Utilities for prod types
*)
open Constr
open Names
open Apputils
let coq_init_data =
ModPath.MPfile
(DirPath.make (List.map Id.of_string ["Datatypes"; "Init"; "Coq"]))
(* --- Constants --- *)
(* prod types *)
let prod : types =
mkInd (MutInd.make1 (KerName.make coq_init_data (Label.make "prod")), 0)
(* Introduction for sigma types *)
let pair : constr =
mkConstruct (fst (destInd prod), 1)
(* Elimination for sigma types *)
let prod_rect : constr =
mkConst (Constant.make2 coq_init_data (Label.make "prod_rect"))
(* First projection *)
let fst : constr =
mkConst (Constant.make2 coq_init_data (Label.make "fst"))
(* Second projection *)
let snd : constr =
mkConst (Constant.make2 coq_init_data (Label.make "snd"))
(* --- Representations --- *)
(*
* An application of pair
*)
type pair_app =
{
typ1 : constr;
typ2 : constr;
trm1 : constr;
trm2 : constr;
}
(*
* Apply a pair_app
*)
let apply_pair (app : pair_app) =
mkAppl (pair, [app.typ1; app.typ2; app.trm1; app.trm2])
(*
* Deconsruct a sigT type from a type
*)
let dest_pair (trm : constr) =
match unfold_args trm with
| [typ1; typ2; trm1; trm2] ->
{ typ1; typ2; trm1; trm2 }
| _ -> assert false
(*
* An application of prod
*)
type prod_app =
{
typ1 : types;
typ2 : types;
}
(*
* Apply a prod_app
*)
let apply_prod (app : prod_app) : types =
mkAppl (prod, [app.typ1; app.typ2])
(*
* Deconstruct a prod
*)
let dest_prod (trm : types) : prod_app =
match unfold_args trm with
| [typ1; typ2] ->
{ typ1; typ2 }
| _ -> assert false
(*
* An application of prod_rect
*)
type prod_elim =
{
to_elim : prod_app;
p : types;
proof : constr;
arg : constr;
}
(*
* Eliminate a prod
*)
let elim_prod (app : prod_elim) =
let typ1 = app.to_elim.typ1 in
let typ2 = app.to_elim.typ2 in
let p = app.p in
let proof = app.proof in
let arg = app.arg in
mkAppl (prod_rect, [typ1; typ2; p; proof; arg])
(*
* Deconstruct an application of prod
*)
let dest_prod_elim (trm : constr) =
match unfold_args trm with
| [typ1; typ2; p; proof; arg] ->
let to_elim = { typ1; typ2 } in
{ to_elim; p; proof; arg }
| _ -> assert false
(*
* First projection of a prod
*)
let prod_fst (app : prod_app) trm =
mkAppl (fst, [app.typ1; app.typ2; trm])
(*
* Second projection of a prod
*)
let prod_snd (app : prod_app) trm =
mkAppl (snd, [app.typ1; app.typ2; trm])
(*
* Both projections of a prod
*)
let prod_projections (app : prod_app) trm =
(prod_fst app trm, prod_snd app trm)