///|
pub(all) struct ConflictDetector {
hostile_matrix : HostileMatrix
topology_matrix : HostileMatrix
} derive(Debug)
///|
pub fn ConflictDetector::new(
table : @interlocking.InterlockingTable,
) -> ConflictDetector {
let hm = HostileMatrix::build_from_interlocking_table(table)
let tm = HostileMatrix::build_topological_conflict_table(table)
{ hostile_matrix: hm, topology_matrix: tm }
}
///|
pub fn ConflictDetector::is_route_allowed(
self : ConflictDetector,
table : @interlocking.InterlockingTable,
candidate_route_id : @interlocking.RouteId,
) -> Result[Unit, String] {
// 1. Bitmask fast check against active routes
let active_mask = RouteBitSet::empty()
for r_id_int, _ in table.active_routes {
if table.is_route_reserved(@interlocking.RouteId::new(r_id_int)) {
active_mask.set(r_id_int)
}
}
if self.hostile_matrix.is_conflict_with_active_mask(
candidate_route_id, active_mask,
) {
return Err("Fast Bitmask Rejection: Hostile route is currently active!")
}
// 2. Detailed dynamic topological check
match table.get_rule(candidate_route_id) {
None => Err("Candidate route rule not found")
Some(candidate_rule) => {
for _, active_state in table.active_routes {
if !table.is_route_reserved(active_state.rule.id) {
continue
}
let active_rule = active_state.rule
match detect_topological_conflicts(candidate_rule, active_rule) {
Some(conflict) =>
return Err(
"Topological Conflict (" +
conflict.conflict_type +
"): " +
conflict.conflicting_element,
)
None => ()
}
}
Ok(())
}
}
}
///|
pub fn ConflictDetector::is_route_allowed_fast(
self : ConflictDetector,
table : @interlocking.InterlockingTable,
candidate_route_id : @interlocking.RouteId,
) -> Bool {
let active_mask = RouteBitSet::empty()
for r_id_int, _ in table.active_routes {
if table.is_route_reserved(@interlocking.RouteId::new(r_id_int)) {
active_mask.set(r_id_int)
}
}
!self.hostile_matrix.is_conflict_with_active_mask(
candidate_route_id, active_mask,
) &&
!self.topology_matrix.is_conflict_with_active_mask(
candidate_route_id, active_mask,
)
}