use crate::resel::{Resel};
use crate::reselboard::{ReselBoard};
use crate::regionmap::{RegionMap};
#[derive(Debug, Clone)]
pub struct IncidenceMap {
pub input_inc_wires: Vec<Vec<usize>>,
pub logic_inc_inputs: Vec<Vec<usize>>,
pub output_inc_inputs: Vec<Vec<usize>>,
pub output_inc_logics: Vec<Vec<usize>>,
pub wire_inc_outputs: Vec<Vec<usize>>,
}
fn incidencemap_from_regionmap(
rm: &RegionMap
) -> IncidenceMap {
let mut input_inc_wires: Vec<Vec<usize>> = vec![];
let mut logic_inc_inputs: Vec<Vec<usize>> = vec![];
let mut output_inc_inputs: Vec<Vec<usize>> = vec![];
let mut output_inc_logics: Vec<Vec<usize>> = vec![];
let mut wire_inc_outputs: Vec<Vec<usize>> = vec![];
for (x_inc_y, x_regions, y_condition) in [
(&mut input_inc_wires, &rm.input_regions, Box::new(|y: Resel| y.is_wire()) as Box<dyn Fn(Resel) -> bool>),
(&mut logic_inc_inputs, &rm.logic_regions, Box::new(|y: Resel| y.is_input()) as Box<dyn Fn(Resel) -> bool>),
(&mut output_inc_inputs, &rm.output_regions, Box::new(|y: Resel| y.is_input()) as Box<dyn Fn(Resel) -> bool>),
(&mut output_inc_logics, &rm.output_regions, Box::new(|y: Resel| y.is_logic()) as Box<dyn Fn(Resel) -> bool>),
(&mut wire_inc_outputs, &rm.wire_regions, Box::new(|y: Resel| y.is_output()) as Box<dyn Fn(Resel) -> bool>),
] {
for (x_i, ri) in x_regions.iter().enumerate() {
assert_eq!(x_i, x_inc_y.len());
x_inc_y.push(vec![]);
for adj_ri in rm.get_adjacent_regions(*ri) {
if y_condition(rm.region_to_resel[adj_ri]) {
x_inc_y[x_i].push(rm.reverse_dense[adj_ri])
}
}
}
}
IncidenceMap{
input_inc_wires,
logic_inc_inputs,
output_inc_inputs,
output_inc_logics,
wire_inc_outputs,
}
}
impl From<RegionMap> for IncidenceMap {
fn from(rm: RegionMap) -> IncidenceMap {
incidencemap_from_regionmap(&rm)
}
}
impl From<&RegionMap> for IncidenceMap {
fn from(rm: &RegionMap) -> IncidenceMap {
incidencemap_from_regionmap(rm)
}
}
#[cfg(test)]
mod reselboard_tests {
use super::*;
use crate::reselboard::{
load_image_from_filename,
};
use crate::regionmap::{RegionMap};
#[test]
fn test_incident_map_on_half_adder() {
let rb = ReselBoard::from(
load_image_from_filename(
"./src/testing/test_half_adder.png"
).unwrap()
);
let rm = RegionMap::from(&rb);
let im = IncidenceMap::from(&rm);
assert_eq!(
im.input_inc_wires,
vec![vec![0,1]]
);
assert_eq!(
im.logic_inc_inputs,
vec![vec![0], vec![0]]
);
assert_eq!(
im.output_inc_inputs,
vec![vec![], vec![]]
);
assert_eq!(
im.output_inc_logics,
vec![vec![0], vec![1],]
);
assert_eq!(
im.wire_inc_outputs,
vec![vec![],vec![],vec![0],vec![1],]
);
}
}