@@ -27,7 +27,7 @@ struct Literal {
27
27
}
28
28
29
29
impl DnfExpr {
30
- pub fn new ( expr : CfgExpr ) -> Self {
30
+ pub fn new ( expr : & CfgExpr ) -> Self {
31
31
let builder = Builder { expr : DnfExpr { conjunctions : Vec :: new ( ) } } ;
32
32
33
33
builder. lower ( expr)
@@ -154,9 +154,9 @@ impl fmt::Display for DnfExpr {
154
154
}
155
155
156
156
impl Conjunction {
157
- fn new ( parts : Vec < CfgExpr > ) -> Self {
157
+ fn new ( parts : Box < [ CfgExpr ] > ) -> Self {
158
158
let mut literals = Vec :: new ( ) ;
159
- for part in parts {
159
+ for part in parts. into_vec ( ) {
160
160
match part {
161
161
CfgExpr :: Invalid | CfgExpr :: Atom ( _) | CfgExpr :: Not ( _) => {
162
162
literals. push ( Literal :: new ( part) ) ;
@@ -232,27 +232,28 @@ struct Builder {
232
232
}
233
233
234
234
impl Builder {
235
- fn lower ( mut self , expr : CfgExpr ) -> DnfExpr {
235
+ fn lower ( mut self , expr : & CfgExpr ) -> DnfExpr {
236
236
let expr = make_nnf ( expr) ;
237
237
let expr = make_dnf ( expr) ;
238
238
239
239
match expr {
240
240
CfgExpr :: Invalid | CfgExpr :: Atom ( _) | CfgExpr :: Not ( _) => {
241
- self . expr . conjunctions . push ( Conjunction :: new ( vec ! [ expr] ) ) ;
241
+ self . expr . conjunctions . push ( Conjunction :: new ( Box :: new ( [ expr] ) ) ) ;
242
242
}
243
243
CfgExpr :: All ( conj) => {
244
244
self . expr . conjunctions . push ( Conjunction :: new ( conj) ) ;
245
245
}
246
- CfgExpr :: Any ( mut disj) => {
246
+ CfgExpr :: Any ( disj) => {
247
+ let mut disj = disj. into_vec ( ) ;
247
248
disj. reverse ( ) ;
248
249
while let Some ( conj) = disj. pop ( ) {
249
250
match conj {
250
251
CfgExpr :: Invalid | CfgExpr :: Atom ( _) | CfgExpr :: All ( _) | CfgExpr :: Not ( _) => {
251
- self . expr . conjunctions . push ( Conjunction :: new ( vec ! [ conj] ) ) ;
252
+ self . expr . conjunctions . push ( Conjunction :: new ( Box :: new ( [ conj] ) ) ) ;
252
253
}
253
254
CfgExpr :: Any ( inner_disj) => {
254
255
// Flatten.
255
- disj. extend ( inner_disj. into_iter ( ) . rev ( ) ) ;
256
+ disj. extend ( inner_disj. into_vec ( ) . into_iter ( ) . rev ( ) ) ;
256
257
}
257
258
}
258
259
}
@@ -266,11 +267,11 @@ impl Builder {
266
267
fn make_dnf ( expr : CfgExpr ) -> CfgExpr {
267
268
match expr {
268
269
CfgExpr :: Invalid | CfgExpr :: Atom ( _) | CfgExpr :: Not ( _) => expr,
269
- CfgExpr :: Any ( e) => flatten ( CfgExpr :: Any ( e. into_iter ( ) . map ( make_dnf) . collect ( ) ) ) ,
270
+ CfgExpr :: Any ( e) => flatten ( CfgExpr :: Any ( e. into_vec ( ) . into_iter ( ) . map ( make_dnf) . collect ( ) ) ) ,
270
271
CfgExpr :: All ( e) => {
271
- let e = e. into_iter ( ) . map ( make_dnf) . collect :: < Vec < _ > > ( ) ;
272
+ let e = e. into_vec ( ) . into_iter ( ) . map ( make_dnf) . collect :: < Vec < _ > > ( ) ;
272
273
273
- flatten ( CfgExpr :: Any ( distribute_conj ( & e) ) )
274
+ flatten ( CfgExpr :: Any ( distribute_conj ( & e) . into_boxed_slice ( ) ) )
274
275
}
275
276
}
276
277
}
@@ -281,7 +282,7 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> {
281
282
match rest {
282
283
[ head, tail @ ..] => match head {
283
284
CfgExpr :: Any ( disj) => {
284
- for part in disj {
285
+ for part in disj. iter ( ) {
285
286
with. push ( part. clone ( ) ) ;
286
287
go ( out, with, tail) ;
287
288
with. pop ( ) ;
@@ -295,7 +296,7 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> {
295
296
} ,
296
297
_ => {
297
298
// Turn accumulated parts into a new conjunction.
298
- out. push ( CfgExpr :: All ( with. clone ( ) ) ) ;
299
+ out. push ( CfgExpr :: All ( with. clone ( ) . into_boxed_slice ( ) ) ) ;
299
300
}
300
301
}
301
302
}
@@ -308,25 +309,27 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> {
308
309
out
309
310
}
310
311
311
- fn make_nnf ( expr : CfgExpr ) -> CfgExpr {
312
+ fn make_nnf ( expr : & CfgExpr ) -> CfgExpr {
312
313
match expr {
313
- CfgExpr :: Invalid | CfgExpr :: Atom ( _) => expr,
314
- CfgExpr :: Any ( expr) => CfgExpr :: Any ( expr. into_iter ( ) . map ( make_nnf) . collect ( ) ) ,
315
- CfgExpr :: All ( expr) => CfgExpr :: All ( expr. into_iter ( ) . map ( make_nnf) . collect ( ) ) ,
316
- CfgExpr :: Not ( operand) => match * operand {
317
- CfgExpr :: Invalid | CfgExpr :: Atom ( _) => CfgExpr :: Not ( operand. clone ( ) ) , // Original negated expr
318
- CfgExpr :: Not ( expr) => {
319
- // Remove double negation.
320
- make_nnf ( * expr)
321
- }
322
- // Convert negated conjunction/disjunction using DeMorgan's Law.
323
- CfgExpr :: Any ( inner) => CfgExpr :: All (
324
- inner. into_iter ( ) . map ( |expr| make_nnf ( CfgExpr :: Not ( Box :: new ( expr) ) ) ) . collect ( ) ,
325
- ) ,
326
- CfgExpr :: All ( inner) => CfgExpr :: Any (
327
- inner. into_iter ( ) . map ( |expr| make_nnf ( CfgExpr :: Not ( Box :: new ( expr) ) ) ) . collect ( ) ,
328
- ) ,
329
- } ,
314
+ CfgExpr :: Invalid | CfgExpr :: Atom ( _) => expr. clone ( ) ,
315
+ CfgExpr :: Any ( expr) => CfgExpr :: Any ( expr. iter ( ) . map ( make_nnf) . collect ( ) ) ,
316
+ CfgExpr :: All ( expr) => CfgExpr :: All ( expr. iter ( ) . map ( make_nnf) . collect ( ) ) ,
317
+ CfgExpr :: Not ( operand) => make_nnf_neg ( operand) ,
318
+ }
319
+ }
320
+
321
+ fn make_nnf_neg ( operand : & CfgExpr ) -> CfgExpr {
322
+ match operand {
323
+ // Original negated expr
324
+ CfgExpr :: Invalid => CfgExpr :: Not ( Box :: new ( CfgExpr :: Invalid ) ) , // Original negated expr
325
+ // Original negated expr
326
+ CfgExpr :: Atom ( atom) => CfgExpr :: Not ( Box :: new ( CfgExpr :: Atom ( atom. clone ( ) ) ) ) ,
327
+ // Remove double negation.
328
+ CfgExpr :: Not ( expr) => make_nnf ( expr) ,
329
+ // Convert negated conjunction/disjunction using DeMorgan's Law.
330
+ CfgExpr :: Any ( inner) => CfgExpr :: All ( inner. iter ( ) . map ( make_nnf_neg) . collect ( ) ) ,
331
+ // Convert negated conjunction/disjunction using DeMorgan's Law.
332
+ CfgExpr :: All ( inner) => CfgExpr :: Any ( inner. iter ( ) . map ( make_nnf_neg) . collect ( ) ) ,
330
333
}
331
334
}
332
335
@@ -335,20 +338,22 @@ fn flatten(expr: CfgExpr) -> CfgExpr {
335
338
match expr {
336
339
CfgExpr :: All ( inner) => CfgExpr :: All (
337
340
inner
338
- . into_iter ( )
341
+ . iter ( )
339
342
. flat_map ( |e| match e {
340
- CfgExpr :: All ( inner) => inner,
341
- _ => vec ! [ e ] ,
343
+ CfgExpr :: All ( inner) => inner. as_ref ( ) ,
344
+ _ => std :: slice :: from_ref ( e ) ,
342
345
} )
346
+ . cloned ( )
343
347
. collect ( ) ,
344
348
) ,
345
349
CfgExpr :: Any ( inner) => CfgExpr :: Any (
346
350
inner
347
- . into_iter ( )
351
+ . iter ( )
348
352
. flat_map ( |e| match e {
349
- CfgExpr :: Any ( inner) => inner,
350
- _ => vec ! [ e ] ,
353
+ CfgExpr :: Any ( inner) => inner. as_ref ( ) ,
354
+ _ => std :: slice :: from_ref ( e ) ,
351
355
} )
356
+ . cloned ( )
352
357
. collect ( ) ,
353
358
) ,
354
359
_ => expr,
0 commit comments