Skip to content

Commit

Permalink
Ensurers without a payload are now 'Guards'.
Browse files Browse the repository at this point in the history
Updated ensurance system method names so they no longer clash.
  • Loading branch information
Emoun committed Nov 17, 2024
1 parent 1f361ae commit 15a6d9a
Show file tree
Hide file tree
Showing 39 changed files with 244 additions and 233 deletions.
8 changes: 4 additions & 4 deletions src/algo/tarjan_scc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use crate::{
core::{
property::{ConnectedGraph, HasVertex},
proxy::SubgraphProxy,
Directed, EnsureUnloaded, Graph,
Directed, Graph, Guard,
},
};
use std::cmp::min;
Expand Down Expand Up @@ -82,7 +82,7 @@ use std::cmp::min;
/// # algo::TarjanScc,
/// # common::AdjListGraph,
/// # core::{
/// # EnsureUnloaded,
/// # Guard,
/// # property::{
/// # NewVertex, AddEdge, HasVertexGraph, Subgraph
/// # }
Expand All @@ -106,7 +106,7 @@ use std::cmp::min;
/// graph.add_edge(&v0,&v2).unwrap();
///
/// // We use `HasVertexGraph` because we don't care where we start
/// let graph = HasVertexGraph::ensure(graph).unwrap();
/// let graph = HasVertexGraph::guard(graph).unwrap();
///
/// // Initialize algorithm
/// let mut tarj = TarjanScc::new(&graph);
Expand Down Expand Up @@ -253,7 +253,7 @@ where
}

return Some(
ConnectedGraph::ensure(scc)
ConnectedGraph::guard(scc)
.expect("Tarjans algorithm produced non-strongly-connected subgraph"),
);
// return Some(ConnectedGraph::new(scc));
Expand Down
4 changes: 2 additions & 2 deletions src/common/ensured.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ impl<G: Ensure> EnsuredGraph<G>
{
if self.0.graph().contains_vertex(v)
{
Some(VertexInGraph::ensure_unvalidated(self.0, v))
Some(VertexInGraph::ensure_unchecked(self.0, v))
}
else
{
Expand All @@ -39,7 +39,7 @@ where
) -> Result<VertexInGraph<G>, ()>
{
let v = self.0.graph_mut().new_vertex_weighted(w)?;
Ok(VertexInGraph::ensure_unvalidated(self.0, v))
Ok(VertexInGraph::ensure_unchecked(self.0, v))
}

pub fn new_vertex(self) -> Result<VertexInGraph<G>, ()>
Expand Down
111 changes: 65 additions & 46 deletions src/core/ensure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,9 @@ pub trait BaseGraph: Sized + GraphDeref
G::ensure_all(self, p)
}
}
pub trait BaseGraphUnloaded: BaseGraph
pub trait BaseGraphGuard: BaseGraph
{
fn ensure_all<G>(self) -> Result<G, ()>
fn guard_all<G>(self) -> Result<G, ()>
where
G: Ensure<Base = Self>,
G::Payload: Payload<(), Item = ()>,
Expand All @@ -72,26 +72,26 @@ pub trait BaseGraphUnloaded: BaseGraph
/// An implementing type ensures a base graph implementation.
///
/// Multiple levels of ensurers are supported.
pub trait Ensure: Release
pub trait Ensure: ReleasePayload
{
fn ensure_unvalidated(
fn ensure_unchecked(
c: Self::Ensured,
p: <Self::Payload as Payload<<Self::Ensured as Release>::Payload>>::Item,
p: <Self::Payload as Payload<<Self::Ensured as ReleasePayload>::Payload>>::Item,
) -> Self;

fn validate(
fn can_ensure(
c: &Self::Ensured,
p: &<Self::Payload as Payload<<Self::Ensured as Release>::Payload>>::Item,
p: &<Self::Payload as Payload<<Self::Ensured as ReleasePayload>::Payload>>::Item,
) -> bool;

fn ensure(
c: Self::Ensured,
p: <Self::Payload as Payload<<Self::Ensured as Release>::Payload>>::Item,
p: <Self::Payload as Payload<<Self::Ensured as ReleasePayload>::Payload>>::Item,
) -> Result<Self, ()>
{
if Self::validate(&c, &p)
if Self::can_ensure(&c, &p)
{
Ok(Self::ensure_unvalidated(c, p))
Ok(Self::ensure_unchecked(c, p))
}
else
{
Expand All @@ -105,89 +105,108 @@ pub trait Ensure: Release
Self::ensure(Self::Ensured::ensure_all(g, rest)?, p)
}
}
pub trait EnsureUnloaded: Ensure
pub trait Guard: Ensure
where
<Self as Release>::Payload:
Payload<<<Self as Release>::Ensured as Release>::Payload, Item = ()>,
<Self as ReleasePayload>::Payload:
Payload<<<Self as ReleasePayload>::Ensured as ReleasePayload>::Payload, Item = ()>,
{
fn ensure_unvalidated(c: Self::Ensured) -> Self
fn guard_unchecked(c: Self::Ensured) -> Self
{
<Self as Ensure>::ensure_unvalidated(c, ())
<Self as Ensure>::ensure_unchecked(c, ())
}
fn validate(c: &Self::Ensured) -> bool
fn can_guard(c: &Self::Ensured) -> bool
{
<Self as Ensure>::validate(c, &())
<Self as Ensure>::can_ensure(c, &())
}
fn ensure(c: Self::Ensured) -> Result<Self, ()>
fn guard(c: Self::Ensured) -> Result<Self, ()>
{
<Self as Ensure>::ensure(c, ())
}
fn ensure_all(g: Self::Base) -> Result<Self, ()>
fn guard_all(g: Self::Base) -> Result<Self, ()>
where
<Self as Release>::Payload: Payload<(), Item = ()>,
<Self as ReleasePayload>::Payload: Payload<(), Item = ()>,
{
Ensure::ensure_all(g, <<Self as Release>::Payload>::new((), ()))
Ensure::ensure_all(g, <<Self as ReleasePayload>::Payload>::new((), ()))
}
}

pub trait Release: Sized + GraphDeref
/// Trait for remove one or more layers of ensurers, aka. releasing the
/// properties.
///
/// A _layer_ is an ensurer that ensures some property holds.
/// The base graph does not count as a layer, the ensurer wrapping the base
/// graph is therefore the first layer. Each layer may need a payload. For
/// example, an ensurer guaranteeing that a given vertex exists may have the
/// vertex as a payload.
///
pub trait ReleasePayload: Sized + GraphDeref
{
/// The base graph implementation being ensured
type Base: BaseGraph;

/// The next level of properties.
/// The inner ensurer being further ensured.
type Ensured: Ensure<Base = Self::Base>;
type Payload: Payload<<Self::Ensured as Release>::Payload>;

/// Release only this level's properties, maintaining
/// the next level's properties
/// The payload used to ensure this property holds.
type Payload: Payload<<Self::Ensured as ReleasePayload>::Payload>;

/// ReleasePayload only this level's properties, maintaining
/// the next level's properties and returning the payload released
fn release(
self,
) -> (
Self::Ensured,
<Self::Payload as Payload<<Self::Ensured as Release>::Payload>>::Item,
<Self::Payload as Payload<<Self::Ensured as ReleasePayload>::Payload>>::Item,
);

/// Fully release this type, returning the base graph implementation
/// type
/// Fully release all ensurers, returning the base graph and the payload for
/// all levels
fn release_all(self) -> (Self::Base, Self::Payload)
{
let (ensured, payload) = self.release();
let (base, payload_rest) = Release::release_all(ensured);
let (base, payload_rest) = ReleasePayload::release_all(ensured);
(base, Payload::new(payload, payload_rest))
}
}
pub trait ReleaseUnloaded: Release

/// Equivalent to `ReleasePayload` except does not return any payload.
pub trait Release: ReleasePayload
{
/// Release only this level's properties, maintaining
/// the next level's properties
/// ReleasePayload only this level's properties, maintaining
/// the next level's properties and returning the payload released
///
/// Like [ReleasePayload::release], but does not return the payload
/// released.
fn release(self) -> Self::Ensured
{
Release::release(self).0
ReleasePayload::release(self).0
}

/// Fully release this type, returning the base graph implementation
/// type
/// Fully release all ensurers, returning the base graph and the payload for
/// all levels
///
/// Like [ReleasePayload::release_all], but does not return the payloads
/// released.
fn release_all(self) -> Self::Base
{
Release::release_all(self).0
ReleasePayload::release_all(self).0
}
}

impl<G: Graph, D: Deref<Target = G>> BaseGraph for D {}
impl<B: BaseGraph> Ensure for B
{
fn ensure_unvalidated(
fn ensure_unchecked(
c: Self::Ensured,
_: <Self::Payload as Payload<<Self::Ensured as Release>::Payload>>::Item,
_: <Self::Payload as Payload<<Self::Ensured as ReleasePayload>::Payload>>::Item,
) -> Self
{
c
}

fn validate(
fn can_ensure(
_: &Self::Ensured,
_: &<Self::Payload as Payload<<Self::Ensured as Release>::Payload>>::Item,
_: &<Self::Payload as Payload<<Self::Ensured as ReleasePayload>::Payload>>::Item,
) -> bool
{
true
Expand All @@ -198,7 +217,7 @@ impl<B: BaseGraph> Ensure for B
Ensure::ensure(g, ())
}
}
impl<B: BaseGraph> Release for B
impl<B: BaseGraph> ReleasePayload for B
{
type Base = Self;
type Ensured = Self;
Expand All @@ -214,9 +233,9 @@ impl<B: BaseGraph> Release for B
(self, ())
}
}
impl<B: BaseGraph> BaseGraphUnloaded for B {}
impl<E: Ensure> EnsureUnloaded for E where
E::Payload: Payload<<E::Ensured as Release>::Payload, Item = ()>
impl<B: BaseGraph> BaseGraphGuard for B {}
impl<E: Ensure> Guard for E where
E::Payload: Payload<<E::Ensured as ReleasePayload>::Payload, Item = ()>
{
}
impl<E: Release> ReleaseUnloaded for E {}
impl<E: ReleasePayload> Release for E {}
6 changes: 3 additions & 3 deletions src/core/property/acyclic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ pub struct AcyclicGraph<C: Ensure>(C);

impl<C: Ensure> Ensure for AcyclicGraph<C>
{
fn ensure_unvalidated(c: Self::Ensured, _: ()) -> Self
fn ensure_unchecked(c: Self::Ensured, _: ()) -> Self
{
Self(c)
}

fn validate(c: &Self::Ensured, _: &()) -> bool
fn can_ensure(c: &Self::Ensured, _: &()) -> bool
{
fn on_visit<G: Graph>(dfs: &mut Dfs<G, (Vec<G::Vertex>, &mut bool)>, v: G::Vertex)
{
Expand Down Expand Up @@ -73,7 +73,7 @@ impl<C: Ensure> Ensure for AcyclicGraph<C>
if !done.contains(&v)
{
done.push(v); // not returned by the dfs
let g = VertexInGraph::ensure_unvalidated(c.graph(), v);
let g = VertexInGraph::ensure_unchecked(c.graph(), v);
let dfs = Dfs::new(&g, on_visit, on_exit, on_explore, (Vec::new(), &mut result));

dfs.for_each(|v| {
Expand Down
10 changes: 5 additions & 5 deletions src/core/property/connected.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub trait Connected: Unilateral
{
self.all_vertices()
.fold(Self::EdgeWeight::zero(), |max_ecc, v| {
let new_ecc = VertexInGraph::ensure_unvalidated(self, v).eccentricity();
let new_ecc = VertexInGraph::ensure_unchecked(self, v).eccentricity();
if new_ecc > max_ecc
{
new_ecc
Expand All @@ -80,7 +80,7 @@ pub trait Connected: Unilateral
{
self.all_vertices()
.fold(Self::EdgeWeight::zero(), |min_ecc, v| {
let new_ecc = VertexInGraph::ensure_unvalidated(self, v).eccentricity();
let new_ecc = VertexInGraph::ensure_unchecked(self, v).eccentricity();
if new_ecc < min_ecc
{
new_ecc
Expand All @@ -104,7 +104,7 @@ pub trait Connected: Unilateral
{
let radius = self.radius();
self.all_vertices()
.filter(move |v| VertexInGraph::ensure_unvalidated(self, *v).eccentricity() == radius)
.filter(move |v| VertexInGraph::ensure_unchecked(self, *v).eccentricity() == radius)
}
}

Expand All @@ -123,12 +123,12 @@ impl<C: Ensure> ConnectedGraph<C>

impl<C: Ensure> Ensure for ConnectedGraph<C>
{
fn ensure_unvalidated(c: Self::Ensured, _: ()) -> Self
fn ensure_unchecked(c: Self::Ensured, _: ()) -> Self
{
Self(c)
}

fn validate(c: &Self::Ensured, _: &()) -> bool
fn can_ensure(c: &Self::Ensured, _: &()) -> bool
{
let g = c.graph();
let v_count = g.all_vertices().count();
Expand Down
8 changes: 4 additions & 4 deletions src/core/property/directedness_ensurers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ pub struct DirectedGraph<C: Ensure>(C);

impl<C: Ensure> Ensure for DirectedGraph<C>
{
fn ensure_unvalidated(c: Self::Ensured, _: ()) -> Self
fn ensure_unchecked(c: Self::Ensured, _: ()) -> Self
{
Self(c)
}

fn validate(_: &Self::Ensured, _: &()) -> bool
fn can_ensure(_: &Self::Ensured, _: &()) -> bool
{
<<C::Graph as Graph>::Directedness as Directedness>::directed()
}
Expand Down Expand Up @@ -54,12 +54,12 @@ pub struct UndirectedGraph<C: Ensure>(C);

impl<C: Ensure> Ensure for UndirectedGraph<C>
{
fn ensure_unvalidated(c: Self::Ensured, _: ()) -> Self
fn ensure_unchecked(c: Self::Ensured, _: ()) -> Self
{
Self(c)
}

fn validate(_: &Self::Ensured, _: &()) -> bool
fn can_ensure(_: &Self::Ensured, _: &()) -> bool
{
!<<C::Graph as Graph>::Directedness as Directedness>::directed()
}
Expand Down
8 changes: 4 additions & 4 deletions src/core/property/has_vertex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,12 @@ pub struct HasVertexGraph<C: Ensure>(C);

impl<C: Ensure> Ensure for HasVertexGraph<C>
{
fn ensure_unvalidated(c: Self::Ensured, _: ()) -> Self
fn ensure_unchecked(c: Self::Ensured, _: ()) -> Self
{
Self(c)
}

fn validate(c: &Self::Ensured, _: &()) -> bool
fn can_ensure(c: &Self::Ensured, _: &()) -> bool
{
c.graph().all_vertices().next().is_some()
}
Expand Down Expand Up @@ -110,12 +110,12 @@ where

impl<C: Ensure> Ensure for VertexInGraph<C>
{
fn ensure_unvalidated(c: Self::Ensured, v: <C::Graph as Graph>::Vertex) -> Self
fn ensure_unchecked(c: Self::Ensured, v: <C::Graph as Graph>::Vertex) -> Self
{
Self(c, v)
}

fn validate(c: &Self::Ensured, p: &<C::Graph as Graph>::Vertex) -> bool
fn can_ensure(c: &Self::Ensured, p: &<C::Graph as Graph>::Vertex) -> bool
{
c.graph().contains_vertex(*p)
}
Expand Down
Loading

0 comments on commit 15a6d9a

Please sign in to comment.