-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpredicatePriorityQueue.ml
352 lines (274 loc) · 10.2 KB
/
predicatePriorityQueue.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
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
module Heap = Core.Heap (* heapのためだけに、Core依存 *)
module G = ConsGraph.G
module PMap = ConsGraph.PMap
module PSet = ConsGraph.PSet
module Polarity:
sig
type t = private int
val pos: t
val neg: t
val of_string: t -> string
end = struct
type t = int
let pos = 1
let neg = 0 (* negativeのが優先順位高いかな *)
let of_string pol =
if pol = pos then "pos"
else if pol = neg then "neg"
else
assert false
end
module PreferedPolarity:
sig
type t = private int
val any:t
val pos:t
val neg:t
val is_prefered: t -> Polarity.t -> bool
end = struct
type t = int
let any = 0
let pos = 1
let neg = 2
let is_prefered (t:t) (pol:Polarity.t) =
(t = any) ||(t = pos && pol = Polarity.pos)||(t = neg && pol = Polarity.neg)
end
module PredicateFixableLevel:
sig
type t = private int
val all: t
val partial: t (* partial is_hinted *)
val twist: t (* prefered polarityと逆の制約でfixableなのがある状態 *)
val zero: t (* zero is_hinted *)
val add_twisted_info: t -> Polarity.t -> PreferedPolarity.t -> int option -> t
val to_string: t -> string
end = struct
type t = int
let all = 0
let partial = 1
let twist = 2
let zero = 3
let add_twisted_info fix_level pol prefere_pol fixable_num_opt =
if PreferedPolarity.is_prefered prefere_pol pol then
fix_level (* no change *)
else if(fix_level = partial)||(fix_level = all && fixable_num_opt <> Some 0) then
twist
else
zero
let to_string t =
if t = all then "all"
else if t = partial then "partial"
else if t = zero then "zero"
else if t = twist then "twist"
else assert false
end
module PredicateInfo = struct
type fixable_cons_info = {fixLevel: PredicateFixableLevel.t
;otherPCount: int option
;fixableNum: int option}
type t ={wholeInfo: fixable_cons_info
;outerInfo: fixable_cons_info option
;pol: Polarity.t
;lavel: G.pLavel }
end
module Priority = struct
(* the most important factor is fixable level *)
type t = {fixLevelIncludeOuter: PredicateFixableLevel.t (* max (fix_levle, outer_fix_level) *)
;fixLevel: PredicateFixableLevel.t
;preferedPol: PreferedPolarity.t
;otherPCount: int
;fixableNum:int
;pol: Polarity.t
;lavel: G.pLavel }
let to_string graph t =
Printf.sprintf "{(%s, %s); otherPCouunt:%d; fixableNum:%d; %s; %s}"
(PredicateFixableLevel.to_string t.fixLevelIncludeOuter)
(PredicateFixableLevel.to_string t.fixLevel)
t.otherPCount
t.fixableNum
(Polarity.of_string t.pol)
(G.id_of_pLavel graph t.lavel)
(* priorityの値が小さい方が優先順位が低い
言葉の意味が反転してしまっている*)
let max = {fixLevelIncludeOuter = PredicateFixableLevel.zero
;fixLevel = PredicateFixableLevel.zero
;preferedPol = PreferedPolarity.neg
;otherPCount = max_int
;fixableNum = max_int
;pol = Polarity.pos
;lavel = G.def_pLavel }
let compare rc1 rc2 =
(* *)
if rc1.fixLevelIncludeOuter <> rc2.fixLevelIncludeOuter then
compare rc1.fixLevelIncludeOuter rc2.fixLevelIncludeOuter
else if rc1.fixLevel <> rc2.fixLevel then
compare rc1.fixLevel rc2.fixLevel
else if rc1.preferedPol <> rc2.preferedPol then
compare rc1.preferedPol rc2.preferedPol
else if rc1.otherPCount <> rc2.otherPCount then
compare rc1.otherPCount rc2.otherPCount
else if rc1.fixableNum <> rc2.fixableNum then
compare rc1.fixableNum rc2.fixableNum
else if rc1.pol <> rc2.pol then
compare rc1.pol rc2.pol
else
compare rc2.lavel rc1.lavel (* 反転 *)
end
module PriorityQueue:
sig
type t
val to_string: G.t -> t -> string
val calc_priority: t -> PredicateInfo.t -> Priority.t
val pop: t -> (G.pLavel * Polarity.t * Priority.t) option
val push_pos: t -> G.pLavel -> Priority.t -> unit
val push_neg: t -> G.pLavel -> Priority.t -> unit
val update_pos: t -> G.pLavel -> Priority.t -> unit
val update_neg: t -> G.pLavel -> Priority.t -> unit
val create: PSet.t -> PSet.t -> int -> t
end = struct
module InternalQueue:
sig
type t = private Priority.t Heap.t
val create: int -> t
val pop: t -> Priority.t option
val push: t -> Priority.t -> unit
end = struct
type t = Priority.t Heap.t
let create size =
Heap.create ~min_size:size ~cmp:Priority.compare ()
let pop heap =
match Heap.pop heap with
|None -> None
|Some priority -> Some priority
let push heap priority= Heap.add heap priority
end
type t = {preferedPol: PreferedPolarity.t array (* neg fixのみのもの *)
;posTable: Priority.t array
;negTable: Priority.t array
;table: Priority.t array
;internalQueue: InternalQueue.t
}
let to_string graph t =
G.fold_p
(fun p acc_str ->
let p = G.int_of_pLavel p in
let pos_priority = t.posTable.(p) in
let neg_priority = t.negTable.(p) in
let min_priority = t.table.(p) in
let str = Printf.sprintf " pos - %s\n neg - %s\n min - %s\n"
(Priority.to_string graph pos_priority)
(Priority.to_string graph neg_priority)
(Priority.to_string graph min_priority)
in
acc_str ^ "\n\n" ^str)
graph
""
(* up_ps は preferedPolは,neg *)
let create_preferedPol up_ps down_ps size =
let arr = Array.make size PreferedPolarity.any in
let () = PSet.iter
(fun p ->
arr.(G.int_of_pLavel p) <- PreferedPolarity.neg
)
up_ps
in
let () = PSet.iter
(fun p ->
arr.(G.int_of_pLavel p) <- PreferedPolarity.pos
)
down_ps
in
arr
let create up_ps down_ps size = (* ここでdummyとしてはpriorityがすぐに更新されるようなもの *)
{preferedPol = create_preferedPol up_ps down_ps size
;posTable = Array.make size Priority.max
;negTable = Array.make size Priority.max
;table = Array.make size Priority.max
;internalQueue = InternalQueue.create size
}
let calc_priority t p_info =
let p = p_info.PredicateInfo.lavel in
let prefer = t.preferedPol.(G.int_of_pLavel p) in
let pol = p_info.PredicateInfo.pol in
let init_fix_level_whole = p_info.PredicateInfo.wholeInfo.fixLevel in
let init_fix_level_outer =
match p_info.PredicateInfo.outerInfo with
|Some {fixLevel = fix_level} -> fix_level
|None -> PredicateFixableLevel.zero
in
let fixable_num_out =
match p_info.PredicateInfo.outerInfo with
|Some {fixableNum = fixable_num} -> fixable_num
|None -> None
in
(* ad-hoc / 今となってはこれが必要かどうかは微妙だ。*)
let fix_level_whole = PredicateFixableLevel.add_twisted_info
init_fix_level_whole
pol
prefer
p_info.PredicateInfo.wholeInfo.fixableNum
in
(* let fix_level_outer = PredicateFixableLevel.add_twisted_info *)
(* init_fix_level_outer *)
(* pol *)
(* prefer *)
(* fixable_num_out *)
(* in *)
let fix_level_outer = init_fix_level_outer in (* twistにしない *)
let pc_count =
match p_info.wholeInfo.otherPCount with
|Some i-> i
|None -> -1 (* dummy *)
in
let fixable_num =
match p_info.wholeInfo.fixableNum with
|Some i-> i
|None -> -1 (* dummy *)
in
Priority.{fixLevelIncludeOuter = min fix_level_whole fix_level_outer
;fixLevel = fix_level_whole
;preferedPol = prefer
;otherPCount = pc_count
;fixableNum = fixable_num
;pol = p_info.PredicateInfo.pol
;lavel = p
}
let rec pop ({table = table; internalQueue = internal_queue} as queue) =
match InternalQueue.pop internal_queue with
|None -> None
|Some priority ->
let p = priority.Priority.lavel in
let priority' = table.(G.int_of_pLavel p) in
if priority = priority' then
Some (p, priority.pol, priority) (* table はpopされた時のものに保たれる *)
else (* updated old element *)
pop queue
let push_pos {preferedPol = prefered_pol
;posTable = pos_table
;negTable = neg_table
;table = table
;internalQueue = internal_queue} p priority =
pos_table.(G.int_of_pLavel p) <- priority; (* table kept up to date *)
let neg_priority = neg_table.(G.int_of_pLavel p) in
let min_priority = min priority neg_priority in
if min_priority < table.(G.int_of_pLavel p) then
(table.(G.int_of_pLavel p) <- min_priority;
InternalQueue.push internal_queue min_priority)
else
()
let push_neg {preferedPol = prefered_pol
;posTable = pos_table
;negTable = neg_table
;table = table
;internalQueue = internal_queue} p priority =
neg_table.(G.int_of_pLavel p) <- priority; (* table kept up to date *)
let pos_priority = pos_table.(G.int_of_pLavel p) in
let min_priority = min priority pos_priority in
if min_priority < pos_table.(G.int_of_pLavel p) then
(table.(G.int_of_pLavel p) <- min_priority;
InternalQueue.push internal_queue min_priority)
else
()
let update_pos = push_pos
let update_neg = push_neg
end