use oxgraph_topology::{
IncidenceBase, IncidenceCounts, IncidenceElement, IncidenceRelation, IncidenceRole,
RelationIncidences, TopologyBase, TopologyCounts,
};
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct VertexId(usize);
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct HyperedgeId(usize);
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct ParticipantId(usize);
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum IncidenceOrientation {
Negative,
Positive,
}
#[derive(Clone, Copy, Debug)]
struct Participant {
hyperedge: HyperedgeId,
vertex: VertexId,
orientation: IncidenceOrientation,
}
#[derive(Debug)]
struct TinyHypergraph {
vertex_count: usize,
hyperedge_count: usize,
participants: &'static [Participant],
}
impl TopologyBase for TinyHypergraph {
type ElementId = VertexId;
type RelationId = HyperedgeId;
}
impl IncidenceBase for TinyHypergraph {
type IncidenceId = ParticipantId;
type Role = IncidenceOrientation;
}
impl TopologyCounts for TinyHypergraph {
fn element_count(&self) -> usize {
self.vertex_count
}
fn relation_count(&self) -> usize {
self.hyperedge_count
}
}
impl IncidenceCounts for TinyHypergraph {
fn incidence_count(&self) -> usize {
self.participants.len()
}
}
impl RelationIncidences for TinyHypergraph {
type Incidences<'view>
= HyperedgeParticipantIter<'view>
where
Self: 'view;
fn relation_incidences(&self, relation: HyperedgeId) -> Self::Incidences<'_> {
HyperedgeParticipantIter {
hypergraph: self,
relation,
next: 0,
}
}
}
impl IncidenceElement for TinyHypergraph {
fn incidence_element(&self, incidence: ParticipantId) -> VertexId {
self.participants[incidence.0].vertex
}
}
impl IncidenceRelation for TinyHypergraph {
fn incidence_relation(&self, incidence: ParticipantId) -> HyperedgeId {
self.participants[incidence.0].hyperedge
}
}
impl IncidenceRole for TinyHypergraph {
fn incidence_role(&self, incidence: ParticipantId) -> IncidenceOrientation {
self.participants[incidence.0].orientation
}
}
struct HyperedgeParticipantIter<'view> {
hypergraph: &'view TinyHypergraph,
relation: HyperedgeId,
next: usize,
}
impl Iterator for HyperedgeParticipantIter<'_> {
type Item = ParticipantId;
fn next(&mut self) -> Option<Self::Item> {
while self.next < self.hypergraph.participants.len() {
let index = self.next;
self.next += 1;
if self.hypergraph.participants[index].hyperedge == self.relation {
return Some(ParticipantId(index));
}
}
None
}
}
fn main() {
static PARTICIPANTS: &[Participant] = &[
Participant {
hyperedge: HyperedgeId(0),
vertex: VertexId(0),
orientation: IncidenceOrientation::Negative,
},
Participant {
hyperedge: HyperedgeId(0),
vertex: VertexId(1),
orientation: IncidenceOrientation::Negative,
},
Participant {
hyperedge: HyperedgeId(0),
vertex: VertexId(2),
orientation: IncidenceOrientation::Positive,
},
];
let hypergraph = TinyHypergraph {
vertex_count: 3,
hyperedge_count: 1,
participants: PARTICIPANTS,
};
for incidence in hypergraph.relation_incidences(HyperedgeId(0)) {
println!(
"hyperedge={:?} incidence={:?} vertex={:?} role={:?}",
hypergraph.incidence_relation(incidence),
incidence,
hypergraph.incidence_element(incidence),
hypergraph.incidence_role(incidence)
);
}
}