-
Notifications
You must be signed in to change notification settings - Fork 524
Expand file tree
/
Copy pathdet.ml
More file actions
217 lines (179 loc) · 6.48 KB
/
det.ml
File metadata and controls
217 lines (179 loc) · 6.48 KB
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
open Util.Source
open Il.Ast
open Il.Free
include Xl.Gen_free
let det_list = free_list
let det_list_dep = free_list_dep
(* Iterations *)
let rec det_iter iter =
match iter with
| Opt | List | List1 -> empty
| ListN (e, _xo) -> det_exp e
(* Types *)
and det_typ t =
Il.Debug.(log_at "il.det_typ" t.at
(fun _ -> fmt "%s" (il_typ t))
(fun s -> String.concat ", " (Set.elements s.varid))
) @@ fun _ ->
match t.it with
| VarT (_x, as_) -> det_list det_arg as_
| BoolT | NumT _ | TextT -> empty
| TupT xts -> det_list_dep det_typbind bound_typbind xts
| IterT (t1, iter) -> det_typ t1 ++ det_iter iter
and det_typbind (_x, t) = det_typ t
and bound_typbind (x, _t) = bound_varid x
(* Expressions *)
and det_exp e =
Il.Debug.(log_at "il.det_exp" e.at
(fun _ -> fmt "%s" (il_exp e))
(fun s -> String.concat ", " (Set.elements s.varid))
) @@ fun _ ->
match e.it with
| VarE x -> bound_varid x
| BoolE _ | NumE _ | TextE _ -> empty
(* We consider arithmetic expressions determinate,
* since we sometimes need to use invertible formulas. *)
| CvtE (e1, _, _) | UnE (#Xl.Num.unop, _, e1) | TheE e1 | LiftE e1
| SubE (e1, _, _) | AnnE (e1, _) -> det_exp e1
| BinE (#Xl.Num.binop, _, e1, e2) | CatE (e1, e2) -> det_exp e1 ++ det_exp e2
| OptE eo -> free_opt det_exp eo
| ListE es | TupE es -> det_list det_exp es
| CaseE (_, e1) | UncaseE (e1, _) -> det_exp e1
| StrE efs -> det_list det_expfield efs
| IterE (e1, ite) -> det_iterexp (det_exp e1) ite
(* As a special hack to work with bijective functions,
* we treat last position of a call as a pattern, too. *)
| CallE (_, []) -> empty
| CallE (_, as_) -> det_list det_idx_arg as_ ++ det_arg (Util.Lib.List.last as_)
| UnE _ | BinE _ | CmpE _
| IdxE _ | SliceE _ | UpdE _ | ExtE _ | CompE _ | MemE _
| ProjE _ | DotE _ | LenE _ -> det_idx_exp e
and det_expfield (_, e) = det_exp e
and det_iterexp s1 (it, xes) =
s1 -- bound_iter it -- free_list bound_varid (List.map fst xes) ++
det_iter it ++
det_list det_exp (List.filter_map
(fun (x, e) -> if Set.mem x.it s1.varid then Some e else None) xes)
and det_cond_exp e =
Il.Debug.(log_at "il.det_cond_exp" e.at
(fun _ -> fmt "%s" (il_exp e))
(fun s -> String.concat ", " (Set.elements s.varid))
) @@ fun _ ->
match e.it with
| UnE (#Xl.Bool.unop, _, e1) -> det_cond_exp e1
| BinE (#Xl.Bool.binop, _, e1, e2) -> det_cond_exp e1 ++ det_cond_exp e2
| CmpE (`EqOp, _, e1, e2) -> det_exp e1 ++ det_exp e2
| MemE (e1, e2) -> det_exp e1 ++ det_quant_exp e2
| _ -> det_quant_exp e
and det_idx_exp e =
Il.Debug.(log_at "il.det_idx_exp" e.at
(fun _ -> fmt "%s" (il_exp e))
(fun s -> String.concat ", " (Set.elements s.varid))
) @@ fun _ ->
match e.it with
| VarE _ -> empty
| LiftE e1 | SubE (e1, _, _) | CaseE (_, e1) -> det_idx_exp e1
| OptE eo -> free_opt det_idx_exp eo
| ListE es | TupE es -> det_list det_idx_exp es
| StrE efs -> det_list det_idx_expfield efs
| IterE (e1, ite) -> det_idx_iterexp (det_idx_exp e1) ite
| CallE (_, as_) -> det_list det_idx_arg as_
| IdxE (e1, e2) -> det_quant_exp e1 ++ det_exp e2
| _ -> det_quant_exp e
and det_idx_expfield (_, e) =
det_idx_exp e
and det_idx_iter iter =
match iter with
| Opt | List | List1 -> empty
| ListN (e, x_opt) -> det_idx_exp e ++ free_opt bound_varid x_opt
and det_idx_iterexp s1 (it, xes) =
s1 -- free_list bound_varid (List.map fst xes) ++
det_idx_iter it ++
det_list det_exp (List.filter_map
(fun (x, e) -> if Set.mem x.it s1.varid then Some e else None) xes)
and det_quant_exp e =
Il.Debug.(log_at "il.det_quant_exp" e.at
(fun _ -> fmt "%s" (il_exp e))
(fun s -> String.concat ", " (Set.elements s.varid))
) @@ fun _ ->
match e.it with
| VarE x -> bound_varid x
| BoolE _ | NumE _ | TextE _ -> empty
| UnE (_, _, e1) | ProjE (e1, _) | TheE e1 | LiftE e1 | LenE e1
| CvtE (e1, _, _) | SubE (e1, _, _) | AnnE (e1, _) ->
det_quant_exp e1
| BinE (_, _, e1, e2) | CmpE (_, _, e1, e2)
| IdxE (e1, e2) | MemE (e1, e2) | CatE (e1, e2) | CompE (e1, e2) ->
det_quant_exp e1 ++ det_quant_exp e2
| SliceE (e1, e2, e3) ->
det_quant_exp e1 ++ det_quant_exp e2 ++ det_quant_exp e3
| UpdE (e1, p, e2) | ExtE (e1, p, e2) ->
det_quant_exp e1 ++ det_quant_path p ++ det_quant_exp e2
| DotE (e1, _) | CaseE (_, e1) | UncaseE (e1, _) -> det_quant_exp e1
| OptE eo -> free_opt det_quant_exp eo
| ListE es | TupE es -> det_list det_quant_exp es
| StrE efs -> det_list det_quant_expfield efs
| IterE (e1, ite) -> det_quant_iterexp (det_quant_exp e1) ite
| CallE (_, as_) -> det_list det_quant_arg as_
and det_quant_expfield (_, e) =
det_quant_exp e
and det_quant_iterexp s1 (it, xes) =
s1 -- bound_iter it -- free_list bound_varid (List.map fst xes) ++
det_quant_iter it ++
det_list det_exp (List.filter_map
(fun (x, e) -> if Set.mem x.it s1.varid then Some e else None) xes)
and det_quant_path p =
match p.it with
| RootP -> empty
| IdxP (p1, e) -> det_quant_path p1 ++ det_quant_exp e
| SliceP (p1, e1, e2) ->
det_quant_path p1 ++ det_quant_exp e1 ++ det_quant_exp e2
| DotP (p1, _) -> det_quant_path p1
and det_quant_iter iter =
match iter with
| Opt | List | List1 -> empty
| ListN (e, _x_opt) -> det_quant_exp e
(* Grammars *)
and det_sym g =
Il.Debug.(log_at "il.det_sym" g.at
(fun _ -> fmt "%s" (il_sym g))
(fun s -> String.concat ", " (Set.elements s.varid))
) @@ fun _ ->
match g.it with
| VarG (_x, as_) -> det_list det_arg as_
| NumG _ | TextG _ | EpsG -> empty
| SeqG gs | AltG gs -> det_list det_sym gs
| RangeG (g1, g2) -> det_sym g1 ++ det_sym g2
| IterG (g1, ite) -> det_iterexp (det_sym g1) ite
| AttrG (e, g1) -> det_exp e ++ det_sym g1
(* Premises *)
and det_prem pr =
Il.Debug.(log_at "il.det_prem" pr.at
(fun _ -> fmt "%s" (il_prem pr))
(fun s -> String.concat ", " (Set.elements s.varid))
) @@ fun _ ->
match pr.it with
| RulePr (_x, _as, _mixop, e) -> det_exp e
| IfPr e -> det_cond_exp e
| LetPr (e1, _e2, _xs) -> det_exp e1
| ElsePr -> empty
| IterPr (pr1, ite) -> det_iterexp (det_prem pr1) ite
(* Definitions *)
and det_arg a =
match a.it with
| ExpA e -> det_exp e
| TypA t -> free_typ t (* must be an id *)
| GramA g -> free_sym g (* must be an id *)
| DefA x -> bound_defid x
and det_idx_arg a =
match a.it with
| ExpA e -> det_idx_exp e
| TypA _ -> empty
| GramA _ -> empty
| DefA _ -> empty
and det_quant_arg a =
match a.it with
| ExpA e -> det_quant_exp e
| TypA _ -> empty
| GramA _ -> empty
| DefA _ -> empty