Skip to content

Commit b0de3e7

Browse files
committed
Fixes a minor bug in parity cycle detection with self-loops.
1 parent b5074e1 commit b0de3e7

File tree

2 files changed

+32
-3
lines changed

2 files changed

+32
-3
lines changed

src/_impl_regulatory_graph/signed_directed_graph/_cycle_detection.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl SdGraph {
144144
}
145145

146146
if upper_bound == 1 {
147-
// Only self-loop can have one edge.
147+
// Only a self-loop can have one edge.
148148
return None;
149149
}
150150

@@ -158,7 +158,10 @@ impl SdGraph {
158158
// Direct predecessors can reach pivot in zero steps.
159159
let mut one_step = HashMap::with_hasher(FxBuildHasher::default());
160160
for (pred, sign) in &self.predecessors[pivot.to_index()] {
161-
if restriction.contains(pred) {
161+
// Pivot should never be inserted here (see also similar condition below), because
162+
// it is already "on the path". Adding it again would mean the result is not
163+
// a simple path.
164+
if restriction.contains(pred) && *pred != pivot {
162165
one_step.insert((*pred, *sign), (pivot, Positive));
163166
}
164167
}

src/_impl_regulatory_graph/signed_directed_graph/_feedback_vertex_set.rs

+27-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ impl SdGraph {
224224
mod tests {
225225
use crate::_impl_regulatory_graph::signed_directed_graph::SdGraph;
226226
use crate::_impl_regulatory_graph::signed_directed_graph::Sign::{Negative, Positive};
227-
use crate::{BooleanNetwork, RegulatoryGraph, VariableId};
227+
use crate::{BooleanNetwork, RegulatoryGraph, Sign, VariableId};
228228
use std::collections::HashSet;
229229

230230
#[test]
@@ -303,4 +303,30 @@ mod tests {
303303
let expected = HashSet::from_iter([VariableId::from_index(2)]);
304304
assert_eq!(expected, bn.as_graph().feedback_vertex_set());
305305
}
306+
307+
#[test]
308+
fn test_feedback_vertex_set_3() {
309+
let bn = BooleanNetwork::try_from(
310+
r#"
311+
a3 -| a3
312+
a5 -| a3
313+
a6 -| a4
314+
a4 -| a5
315+
a4 -| a6
316+
$a3: !a3 & !a5
317+
$a4: !a6
318+
$a5: !a4
319+
$a6: !a4
320+
"#,
321+
)
322+
.unwrap();
323+
324+
let p_fvs = bn.as_graph().parity_feedback_vertex_set(Sign::Positive);
325+
326+
// The graph only has one positive cycle on a4/a6.
327+
let a4 = VariableId::from_index(1);
328+
let a6 = VariableId::from_index(3);
329+
assert!(p_fvs.contains(&a4) || p_fvs.contains(&a6));
330+
assert_eq!(p_fvs.len(), 1);
331+
}
306332
}

0 commit comments

Comments
 (0)