44use super :: Dag ;
55use crate :: edges:: EdgeClass ;
66use crate :: graph:: admg:: Admg ;
7- use crate :: graph:: alg:: csr;
7+ use crate :: graph:: alg:: { csr, meek } ;
88use crate :: graph:: pdag:: Pdag ;
99use crate :: graph:: ug:: Ug ;
1010use crate :: graph:: CaugiGraph ;
11- use std:: collections:: { BTreeSet , HashSet , VecDeque } ;
11+ use std:: collections:: { BTreeSet , HashSet } ;
1212use std:: sync:: Arc ;
1313
1414impl Dag {
@@ -335,62 +335,6 @@ impl Dag {
335335 let mut ch: Vec < HashSet < u32 > > = vec ! [ HashSet :: new( ) ; n] ;
336336 let mut und: Vec < HashSet < u32 > > = vec ! [ HashSet :: new( ) ; n] ;
337337
338- #[ inline]
339- fn adjacent (
340- a : usize ,
341- b : usize ,
342- und : & [ HashSet < u32 > ] ,
343- pa : & [ HashSet < u32 > ] ,
344- ch : & [ HashSet < u32 > ] ,
345- ) -> bool {
346- und[ a] . contains ( & ( b as u32 ) )
347- || und[ b] . contains ( & ( a as u32 ) )
348- || pa[ a] . contains ( & ( b as u32 ) )
349- || ch[ a] . contains ( & ( b as u32 ) )
350- || pa[ b] . contains ( & ( a as u32 ) )
351- || ch[ b] . contains ( & ( a as u32 ) )
352- }
353-
354- #[ inline]
355- fn orient (
356- a : u32 ,
357- b : u32 ,
358- und : & mut [ HashSet < u32 > ] ,
359- pa : & mut [ HashSet < u32 > ] ,
360- ch : & mut [ HashSet < u32 > ] ,
361- ) {
362- let ai = a as usize ;
363- let bi = b as usize ;
364- und[ ai] . remove ( & b) ;
365- und[ bi] . remove ( & a) ;
366- ch[ ai] . insert ( b) ;
367- pa[ bi] . insert ( a) ;
368- }
369-
370- fn has_dir_path ( ch : & [ HashSet < u32 > ] , src : u32 , tgt : u32 ) -> bool {
371- if src == tgt {
372- return true ;
373- }
374- let n = ch. len ( ) ;
375- let mut seen = vec ! [ false ; n] ;
376- let mut q = VecDeque :: new ( ) ;
377- q. push_back ( src) ;
378- while let Some ( u) = q. pop_front ( ) {
379- if u == tgt {
380- return true ;
381- }
382- if std:: mem:: replace ( & mut seen[ u as usize ] , true ) {
383- continue ;
384- }
385- for & v in & ch[ u as usize ] {
386- if !seen[ v as usize ] {
387- q. push_back ( v) ;
388- }
389- }
390- }
391- false
392- }
393-
394338 // Skeleton from DAG (undirected)
395339 for u in 0 ..self . n ( ) {
396340 for & v in self . children_of ( u) {
@@ -406,95 +350,15 @@ impl Dag {
406350 for j in ( i + 1 ) ..parents. len ( ) {
407351 let a = parents[ i] as usize ;
408352 let c = parents[ j] as usize ;
409- if !adjacent ( a, c, & und, & pa, & ch) {
410- orient ( parents[ i] , b, & mut und, & mut pa, & mut ch) ;
411- orient ( parents[ j] , b, & mut und, & mut pa, & mut ch) ;
353+ if !meek :: adjacent ( a, c, & und, & pa, & ch) {
354+ meek :: orient ( parents[ i] , b, & mut und, & mut pa, & mut ch) ;
355+ meek :: orient ( parents[ j] , b, & mut und, & mut pa, & mut ch) ;
412356 }
413357 }
414358 }
415359 }
416360
417- // Meek closure (R1–R4)
418- loop {
419- let mut changed = false ;
420-
421- // R1: a->b, b--c, a !~ c ⇒ b->c
422- for b in 0 ..n {
423- if pa[ b] . is_empty ( ) || und[ b] . is_empty ( ) {
424- continue ;
425- }
426- let pb: Vec < u32 > = pa[ b] . iter ( ) . copied ( ) . collect ( ) ;
427- let ubs: Vec < u32 > = und[ b] . clone ( ) . into_iter ( ) . collect ( ) ;
428- ' c_loop: for c in ubs {
429- let ci = c as usize ;
430- for & a in & pb {
431- if !adjacent ( a as usize , ci, & und, & pa, & ch) {
432- orient ( b as u32 , c, & mut und, & mut pa, & mut ch) ;
433- changed = true ;
434- continue ' c_loop;
435- }
436- }
437- }
438- }
439-
440- // R2: a--b and ∃ w: a->w, w->b ⇒ a->b
441- for a in 0 ..n {
442- let uab: Vec < u32 > = und[ a] . clone ( ) . into_iter ( ) . collect ( ) ;
443- for b_u in uab {
444- let b = b_u as usize ;
445- if ch[ a] . iter ( ) . any ( |w| pa[ b] . contains ( w) ) {
446- orient ( a as u32 , b_u, & mut und, & mut pa, & mut ch) ;
447- changed = true ;
448- continue ;
449- }
450- if ch[ b] . iter ( ) . any ( |w| pa[ a] . contains ( w) ) {
451- orient ( b_u, a as u32 , & mut und, & mut pa, & mut ch) ;
452- changed = true ;
453- }
454- }
455- }
456-
457- // R3: a--b and ∃ c,d: c->b, d->b, c !~ d, a--c, a--d ⇒ a->b
458- for a in 0 ..n {
459- let uab: Vec < u32 > = und[ a] . clone ( ) . into_iter ( ) . collect ( ) ;
460- for b_u in uab {
461- let b = b_u as usize ;
462- let pb: Vec < u32 > = pa[ b] . iter ( ) . copied ( ) . collect ( ) ;
463- ' pairs: for i in 0 ..pb. len ( ) {
464- for j in ( i + 1 ) ..pb. len ( ) {
465- let c = pb[ i] as usize ;
466- let d = pb[ j] as usize ;
467- if !adjacent ( c, d, & und, & pa, & ch)
468- && und[ a] . contains ( & pb[ i] )
469- && und[ a] . contains ( & pb[ j] )
470- {
471- orient ( a as u32 , b_u, & mut und, & mut pa, & mut ch) ;
472- changed = true ;
473- break ' pairs;
474- }
475- }
476- }
477- }
478- }
479-
480- // R4: a--b and (a ⇒ b or b ⇒ a) ⇒ orient along reachability
481- for a in 0 ..n {
482- let uab: Vec < u32 > = und[ a] . clone ( ) . into_iter ( ) . collect ( ) ;
483- for b_u in uab {
484- if has_dir_path ( & ch, a as u32 , b_u) {
485- orient ( a as u32 , b_u, & mut und, & mut pa, & mut ch) ;
486- changed = true ;
487- } else if has_dir_path ( & ch, b_u, a as u32 ) {
488- orient ( b_u, a as u32 , & mut und, & mut pa, & mut ch) ;
489- changed = true ;
490- }
491- }
492- }
493-
494- if !changed {
495- break ;
496- }
497- }
361+ meek:: apply_meek_closure ( & mut pa, & mut ch, & mut und, false ) ;
498362
499363 // Build CSR core (parents | undirected | children)
500364 let specs = & self . core_ref ( ) . registry . specs ;
0 commit comments