@@ -27,7 +27,7 @@ struct Literal {
2727}
2828
2929impl DnfExpr {
30- pub fn new ( expr : CfgExpr ) -> Self {
30+ pub fn new ( expr : & CfgExpr ) -> Self {
3131 let builder = Builder { expr : DnfExpr { conjunctions : Vec :: new ( ) } } ;
3232
3333 builder. lower ( expr)
@@ -154,9 +154,9 @@ impl fmt::Display for DnfExpr {
154154}
155155
156156impl Conjunction {
157- fn new ( parts : Vec < CfgExpr > ) -> Self {
157+ fn new ( parts : Box < [ CfgExpr ] > ) -> Self {
158158 let mut literals = Vec :: new ( ) ;
159- for part in parts {
159+ for part in parts. into_vec ( ) {
160160 match part {
161161 CfgExpr :: Invalid | CfgExpr :: Atom ( _) | CfgExpr :: Not ( _) => {
162162 literals. push ( Literal :: new ( part) ) ;
@@ -232,27 +232,28 @@ struct Builder {
232232}
233233
234234impl Builder {
235- fn lower ( mut self , expr : CfgExpr ) -> DnfExpr {
235+ fn lower ( mut self , expr : & CfgExpr ) -> DnfExpr {
236236 let expr = make_nnf ( expr) ;
237237 let expr = make_dnf ( expr) ;
238238
239239 match expr {
240240 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] ) ) ) ;
242242 }
243243 CfgExpr :: All ( conj) => {
244244 self . expr . conjunctions . push ( Conjunction :: new ( conj) ) ;
245245 }
246- CfgExpr :: Any ( mut disj) => {
246+ CfgExpr :: Any ( disj) => {
247+ let mut disj = disj. into_vec ( ) ;
247248 disj. reverse ( ) ;
248249 while let Some ( conj) = disj. pop ( ) {
249250 match conj {
250251 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] ) ) ) ;
252253 }
253254 CfgExpr :: Any ( inner_disj) => {
254255 // Flatten.
255- disj. extend ( inner_disj. into_iter ( ) . rev ( ) ) ;
256+ disj. extend ( inner_disj. into_vec ( ) . into_iter ( ) . rev ( ) ) ;
256257 }
257258 }
258259 }
@@ -266,11 +267,11 @@ impl Builder {
266267fn make_dnf ( expr : CfgExpr ) -> CfgExpr {
267268 match expr {
268269 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 ( ) ) ) ,
270271 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 < _ > > ( ) ;
272273
273- flatten ( CfgExpr :: Any ( distribute_conj ( & e) ) )
274+ flatten ( CfgExpr :: Any ( distribute_conj ( & e) . into_boxed_slice ( ) ) )
274275 }
275276 }
276277}
@@ -281,7 +282,7 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> {
281282 match rest {
282283 [ head, tail @ ..] => match head {
283284 CfgExpr :: Any ( disj) => {
284- for part in disj {
285+ for part in disj. iter ( ) {
285286 with. push ( part. clone ( ) ) ;
286287 go ( out, with, tail) ;
287288 with. pop ( ) ;
@@ -295,7 +296,7 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> {
295296 } ,
296297 _ => {
297298 // Turn accumulated parts into a new conjunction.
298- out. push ( CfgExpr :: All ( with. clone ( ) ) ) ;
299+ out. push ( CfgExpr :: All ( with. clone ( ) . into_boxed_slice ( ) ) ) ;
299300 }
300301 }
301302 }
@@ -308,25 +309,27 @@ fn distribute_conj(conj: &[CfgExpr]) -> Vec<CfgExpr> {
308309 out
309310}
310311
311- fn make_nnf ( expr : CfgExpr ) -> CfgExpr {
312+ fn make_nnf ( expr : & CfgExpr ) -> CfgExpr {
312313 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 ( ) ) ,
330333 }
331334}
332335
@@ -335,20 +338,22 @@ fn flatten(expr: CfgExpr) -> CfgExpr {
335338 match expr {
336339 CfgExpr :: All ( inner) => CfgExpr :: All (
337340 inner
338- . into_iter ( )
341+ . iter ( )
339342 . 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 ) ,
342345 } )
346+ . cloned ( )
343347 . collect ( ) ,
344348 ) ,
345349 CfgExpr :: Any ( inner) => CfgExpr :: Any (
346350 inner
347- . into_iter ( )
351+ . iter ( )
348352 . 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 ) ,
351355 } )
356+ . cloned ( )
352357 . collect ( ) ,
353358 ) ,
354359 _ => expr,
0 commit comments