layout: Combine primitive creation methods into generics

This commit is contained in:
Mikolaj Wielgus 2023-10-26 14:32:44 +00:00
parent 21ed14ae3d
commit 3619c5eab4
2 changed files with 86 additions and 95 deletions

View File

@ -27,30 +27,30 @@ pub trait GetNet {
} }
macro_rules! impl_type { macro_rules! impl_type {
($weight_struct_name:ident, $weight_variant_name:ident, $index_struct_name:ident) => { ($weight_struct:ident, $weight_variant:ident, $index_struct:ident) => {
impl Retag for $weight_struct_name { impl Retag for $weight_struct {
fn retag(&self, index: NodeIndex<usize>) -> Index { fn retag(&self, index: NodeIndex<usize>) -> Index {
Index::$weight_variant_name($index_struct_name { Index::$weight_variant($index_struct {
node_index: index, node_index: index,
marker: PhantomData, marker: PhantomData,
}) })
} }
} }
impl GetNet for $weight_struct_name { impl GetNet for $weight_struct {
fn net(&self) -> i64 { fn net(&self) -> i64 {
self.net self.net
} }
} }
pub type $index_struct_name = GenericIndex<$weight_struct_name>; pub type $index_struct = GenericIndex<$weight_struct>;
impl MakePrimitive for $index_struct_name { impl MakePrimitive for $index_struct {
fn primitive<'a>( fn primitive<'a>(
&self, &self,
graph: &'a StableDiGraph<Weight, Label, usize>, graph: &'a StableDiGraph<Weight, Label, usize>,
) -> Primitive<'a> { ) -> Primitive<'a> {
Primitive::$weight_variant_name(GenericPrimitive::new(*self, graph)) Primitive::$weight_variant(GenericPrimitive::new(*self, graph))
} }
} }
}; };
@ -137,6 +137,8 @@ impl From<BendIndex> for Index {
} }
} }
pub trait DotWeight: GetNet + Into<Weight> + Copy {}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedDotWeight { pub struct FixedDotWeight {
pub net: i64, pub net: i64,
@ -144,6 +146,7 @@ pub struct FixedDotWeight {
} }
impl_type!(FixedDotWeight, FixedDot, FixedDotIndex); impl_type!(FixedDotWeight, FixedDot, FixedDotIndex);
impl DotWeight for FixedDotWeight {}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct LooseDotWeight { pub struct LooseDotWeight {
@ -152,6 +155,9 @@ pub struct LooseDotWeight {
} }
impl_type!(LooseDotWeight, LooseDot, LooseDotIndex); impl_type!(LooseDotWeight, LooseDot, LooseDotIndex);
impl DotWeight for LooseDotWeight {}
pub trait SegWeight: GetNet + Into<Weight> + Copy {}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedSegWeight { pub struct FixedSegWeight {
@ -160,6 +166,7 @@ pub struct FixedSegWeight {
} }
impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex); impl_type!(FixedSegWeight, FixedSeg, FixedSegIndex);
impl SegWeight for FixedSegWeight {}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct HalfLooseSegWeight { pub struct HalfLooseSegWeight {
@ -168,6 +175,7 @@ pub struct HalfLooseSegWeight {
} }
impl_type!(HalfLooseSegWeight, HalfLooseSeg, HalfLooseSegIndex); impl_type!(HalfLooseSegWeight, HalfLooseSeg, HalfLooseSegIndex);
impl SegWeight for HalfLooseSegWeight {}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct FullyLooseSegWeight { pub struct FullyLooseSegWeight {
@ -176,6 +184,9 @@ pub struct FullyLooseSegWeight {
} }
impl_type!(FullyLooseSegWeight, FullyLooseSeg, FullyLooseSegIndex); impl_type!(FullyLooseSegWeight, FullyLooseSeg, FullyLooseSegIndex);
impl SegWeight for FullyLooseSegWeight {}
pub trait BendWeight: GetNet + Into<Weight> + Copy {}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct FixedBendWeight { pub struct FixedBendWeight {
@ -184,6 +195,7 @@ pub struct FixedBendWeight {
} }
impl_type!(FixedBendWeight, FixedBend, FixedBendIndex); impl_type!(FixedBendWeight, FixedBend, FixedBendIndex);
impl BendWeight for FixedBendWeight {}
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq)]
pub struct LooseBendWeight { pub struct LooseBendWeight {
@ -192,6 +204,7 @@ pub struct LooseBendWeight {
} }
impl_type!(LooseBendWeight, LooseBend, LooseBendIndex); impl_type!(LooseBendWeight, LooseBend, LooseBendIndex);
impl BendWeight for LooseBendWeight {}
#[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)] #[derive(Debug, EnumAsInner, Clone, Copy, PartialEq)]
pub enum Label { pub enum Label {

View File

@ -8,9 +8,10 @@ use rstar::{RTree, RTreeObject};
use crate::bow::Bow; use crate::bow::Bow;
use crate::graph::{ use crate::graph::{
FixedBendIndex, FixedBendWeight, FixedDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight, BendWeight, DotIndex, DotWeight, FixedBendIndex, FixedBendWeight, FixedDotIndex,
GenericIndex, GetNodeIndex, HalfLooseSegWeight, Index, Interior, Label, LooseDotIndex, FixedDotWeight, FixedSegIndex, FixedSegWeight, FullyLooseSegIndex, FullyLooseSegWeight,
LooseDotWeight, MakePrimitive, Retag, Weight, GenericIndex, GetNodeIndex, HalfLooseSegIndex, HalfLooseSegWeight, Index, Interior, Label,
LooseDotIndex, LooseDotWeight, LooseSegIndex, MakePrimitive, Retag, SegWeight, Weight,
}; };
use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape}; use crate::primitive::{GenericPrimitive, GetConnectable, GetWeight, MakeShape};
use crate::segbend::Segbend; use crate::segbend::Segbend;
@ -64,9 +65,17 @@ impl Layout {
self.graph.remove_node(index.node_index()); self.graph.remove_node(index.node_index());
} }
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, ()> { pub fn add_fixed_dot(&mut self, weight: FixedDotWeight) -> Result<FixedDotIndex, ()> {
let dot = FixedDotIndex::new(self.graph.add_node(weight.into())); self.add_dot(weight)
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
fn add_dot<W: DotWeight>(&mut self, weight: W) -> Result<GenericIndex<W>, ()>
where
GenericIndex<W>: Into<Index> + Copy,
{
let dot = GenericIndex::<W>::new(self.graph.add_node(weight.into()));
self.insert_into_rtree(dot.into()); self.insert_into_rtree(dot.into());
self.fail_and_remove_if_collides_except(dot.into(), &[])?; self.fail_and_remove_if_collides_except(dot.into(), &[])?;
@ -74,93 +83,59 @@ impl Layout {
Ok(dot) Ok(dot)
} }
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
pub fn add_loose_dot(&mut self, weight: LooseDotWeight) -> Result<LooseDotIndex, ()> { #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
let dot = LooseDotIndex::new(self.graph.add_node(weight.into())); #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
self.insert_into_rtree(dot.into());
self.fail_and_remove_if_collides_except(dot.into(), &[])?;
Ok(dot)
}
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))]
pub fn add_fixed_seg( pub fn add_fixed_seg(
&mut self, &mut self,
from: FixedDotIndex, from: FixedDotIndex,
to: FixedDotIndex, to: FixedDotIndex,
weight: FixedSegWeight, weight: FixedSegWeight,
) -> Result<FixedSegIndex, ()> { ) -> Result<FixedSegIndex, ()> {
let seg = FixedSegIndex::new(self.graph.add_node(weight.into())); self.add_seg(from, to, weight)
self.graph
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
self.graph
.add_edge(seg.node_index(), to.node_index(), Label::Adjacent);
self.insert_into_rtree(seg.into());
self.fail_and_remove_if_collides_except(seg.into(), &[])?;
self.graph
.node_weight_mut(from.node_index())
.unwrap()
.as_fixed_dot_mut()
.unwrap()
.net = weight.net;
self.graph
.node_weight_mut(to.node_index())
.unwrap()
.as_fixed_dot_mut()
.unwrap()
.net = weight.net;
Ok(seg)
} }
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))] #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
pub fn add_half_loose_seg( pub fn add_half_loose_seg(
&mut self, &mut self,
from: FixedDotIndex, from: FixedDotIndex,
to: LooseDotIndex, to: LooseDotIndex,
weight: HalfLooseSegWeight, weight: HalfLooseSegWeight,
) -> Result<FixedSegIndex, ()> { ) -> Result<HalfLooseSegIndex, ()> {
let seg = FixedSegIndex::new(self.graph.add_node(weight.into())); self.add_seg(from, to, weight)
self.graph
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
self.graph
.add_edge(seg.node_index(), to.node_index(), Label::Adjacent);
self.insert_into_rtree(seg.into());
self.fail_and_remove_if_collides_except(seg.into(), &[])?;
self.graph
.node_weight_mut(from.node_index())
.unwrap()
.as_fixed_dot_mut()
.unwrap()
.net = weight.net;
self.graph
.node_weight_mut(to.node_index())
.unwrap()
.as_fixed_dot_mut()
.unwrap()
.net = weight.net;
Ok(seg)
} }
#[debug_ensures(self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(self.graph.edge_count() == old(self.graph.edge_count() + 2))] #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
pub fn add_loose_seg( #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
pub fn add_fully_loose_seg(
&mut self, &mut self,
from: LooseDotIndex, from: LooseDotIndex,
to: LooseDotIndex, to: LooseDotIndex,
weight: HalfLooseSegWeight, weight: FullyLooseSegWeight,
) -> Result<FixedSegIndex, ()> { ) -> Result<FullyLooseSegIndex, ()> {
let seg = FixedSegIndex::new(self.graph.add_node(weight.into())); self.add_seg(from, to, weight)
}
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 2))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
fn add_seg<W: SegWeight>(
&mut self,
from: impl GetNodeIndex,
to: impl GetNodeIndex,
weight: W,
) -> Result<GenericIndex<W>, ()>
where
GenericIndex<W>: Into<Index> + Copy,
{
let seg = GenericIndex::<W>::new(self.graph.add_node(weight.into()));
self.graph self.graph
.add_edge(from.node_index(), seg.node_index(), Label::Adjacent); .add_edge(from.node_index(), seg.node_index(), Label::Adjacent);
@ -175,13 +150,13 @@ impl Layout {
.unwrap() .unwrap()
.as_fixed_dot_mut() .as_fixed_dot_mut()
.unwrap() .unwrap()
.net = weight.net; .net = weight.net();
self.graph self.graph
.node_weight_mut(to.node_index()) .node_weight_mut(to.node_index())
.unwrap() .unwrap()
.as_fixed_dot_mut() .as_fixed_dot_mut()
.unwrap() .unwrap()
.net = weight.net; .net = weight.net();
Ok(seg) Ok(seg)
} }
@ -202,7 +177,7 @@ impl Layout {
} }
} }
/*#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
pub fn add_loose_bend( pub fn add_loose_bend(
&mut self, &mut self,
@ -216,19 +191,22 @@ impl Layout {
Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight), Index::FixedBend(around) => self.add_outer_bend(from, to, around, weight),
_ => unreachable!(), _ => unreachable!(),
} }
}*/ }
#[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))] #[debug_ensures(ret.is_ok() -> self.graph.node_count() == old(self.graph.node_count() + 1))]
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3))] #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 3))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
pub fn add_core_bend( fn add_core_bend<W: BendWeight>(
&mut self, &mut self,
from: FixedDotIndex, from: impl GetNodeIndex,
to: FixedDotIndex, to: impl GetNodeIndex,
core: FixedDotIndex, core: FixedDotIndex,
weight: FixedBendWeight, weight: W,
) -> Result<FixedBendIndex, ()> { ) -> Result<FixedBendIndex, ()>
where
GenericIndex<W>: Into<Index> + Copy,
{
let bend = FixedBendIndex::new(self.graph.add_node(weight.into())); let bend = FixedBendIndex::new(self.graph.add_node(weight.into()));
self.graph self.graph
@ -247,12 +225,12 @@ impl Layout {
#[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))] #[debug_ensures(ret.is_err() -> self.graph.node_count() == old(self.graph.node_count()))]
#[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 4))] #[debug_ensures(ret.is_ok() -> self.graph.edge_count() == old(self.graph.edge_count() + 4))]
#[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))] #[debug_ensures(ret.is_err() -> self.graph.edge_count() == old(self.graph.edge_count()))]
pub fn add_outer_bend( fn add_outer_bend<W: BendWeight>(
&mut self, &mut self,
from: FixedDotIndex, from: impl GetNodeIndex,
to: FixedDotIndex, to: impl GetNodeIndex,
inner: FixedBendIndex, inner: impl GetNodeIndex,
weight: FixedBendWeight, weight: W,
) -> Result<FixedBendIndex, ()> { ) -> Result<FixedBendIndex, ()> {
let core = *self let core = *self
.graph .graph