fera_graph/graphs/
static_.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use choose::Choose;
6use graphs::common::OutNeighborFromOutEdge;
7use prelude::*;
8use props::{VecEdgeProp, VecVertexProp};
9
10use fera_fun::vec;
11use fera_optional::OptionalMax;
12
13use std::cmp::Ordering;
14use std::fmt::Debug;
15use std::hash::{Hash, Hasher};
16use std::iter::{Cloned, Map};
17use std::marker::PhantomData;
18use std::ops::Range;
19use std::slice::Iter;
20
21use num_traits::Bounded;
22use rand::Rng;
23
24pub type StaticDigraph = Static<u32, (Directed, usize)>;
25
26pub type StaticGraph = Static<u32, (Undirected, usize)>;
27
28// Edge
29
30pub trait StaticEdgeKind: 'static {
31    type Kind: UniformEdgeKind; // TODO: change to EdgeKind
32    type Edge: 'static + GraphItem + Bounded + EdgeImpl;
33}
34
35#[doc(hidden)]
36pub trait EdgeImpl: Sized {
37    fn new(e: usize) -> Self;
38    fn new_checked(e: usize) -> Option<Self>;
39    fn source<T>(self, ends: &[T]) -> &T;
40    fn target<T>(self, ends: &[T]) -> &T;
41    fn to_index(self) -> usize;
42    fn reverse(self) -> Self;
43}
44
45// StaticDirectedEdge
46
47#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
48pub struct StaticDirectedEdge<N: Num>(N);
49
50impl<E: Num> StaticEdgeKind for (Directed, E) {
51    type Kind = Directed;
52    type Edge = StaticDirectedEdge<E>;
53}
54
55impl<N: Num> Bounded for StaticDirectedEdge<N> {
56    fn max_value() -> Self {
57        StaticDirectedEdge(N::max_value())
58    }
59
60    fn min_value() -> Self {
61        StaticDirectedEdge(N::min_value())
62    }
63}
64
65impl<N: Num> EdgeImpl for StaticDirectedEdge<N> {
66    fn new(e: usize) -> Self {
67        StaticDirectedEdge(N::from_usize(e))
68    }
69
70    fn new_checked(e: usize) -> Option<Self> {
71        if N::is_valid(e) {
72            Some(Self::new(e))
73        } else {
74            None
75        }
76    }
77
78    fn source<T>(self, ends: &[T]) -> &T {
79        &ends[2 * N::to_usize(self.0)]
80    }
81
82    fn target<T>(self, ends: &[T]) -> &T {
83        &ends[2 * N::to_usize(self.0) + 1]
84    }
85
86    fn to_index(self) -> usize {
87        N::to_usize(self.0)
88    }
89
90    fn reverse(self) -> Self {
91        panic!("StaticDirectedEdge::reverse should not be called")
92    }
93}
94
95// StaticUndirectedEdge
96
97#[derive(Copy, Clone, Debug, Eq)]
98pub struct StaticUndirectedEdge<N: Num>(N);
99
100impl<E: Num> StaticEdgeKind for (Undirected, E) {
101    type Kind = Undirected;
102    type Edge = StaticUndirectedEdge<E>;
103}
104
105impl<N: Num> Bounded for StaticUndirectedEdge<N> {
106    fn max_value() -> Self {
107        StaticUndirectedEdge(N::max_value())
108    }
109
110    fn min_value() -> Self {
111        StaticUndirectedEdge(N::min_value())
112    }
113}
114
115// TODO: Document the representation of StaticUndirectedEdge
116impl<N: Num> EdgeImpl for StaticUndirectedEdge<N> {
117    fn new(e: usize) -> Self {
118        StaticUndirectedEdge(N::from_usize(e << 1))
119    }
120
121    fn new_checked(e: usize) -> Option<Self> {
122        e.checked_mul(2).and_then(|x| {
123            if N::is_valid(x) {
124                Some(Self::new(e))
125            } else {
126                None
127            }
128        })
129    }
130
131    fn source<T>(self, ends: &[T]) -> &T {
132        &ends[N::to_usize(self.0)]
133    }
134
135    fn target<T>(self, ends: &[T]) -> &T {
136        &ends[N::to_usize(self.0) ^ 1]
137    }
138
139    fn to_index(self) -> usize {
140        N::to_usize(self.0) >> 1
141    }
142
143    fn reverse(self) -> Self {
144        StaticUndirectedEdge(N::from_usize(N::to_usize(self.0) ^ 1))
145    }
146}
147
148impl<N: Num> PartialEq for StaticUndirectedEdge<N> {
149    fn eq(&self, other: &Self) -> bool {
150        self.to_index() == other.to_index()
151    }
152}
153
154impl<N: Num> PartialOrd for StaticUndirectedEdge<N> {
155    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
156        self.to_index().partial_cmp(&other.to_index())
157    }
158}
159
160impl<N: Num> Ord for StaticUndirectedEdge<N> {
161    fn cmp(&self, other: &Self) -> Ordering {
162        self.to_index().cmp(&other.to_index())
163    }
164}
165
166impl<N: Num> Hash for StaticUndirectedEdge<N> {
167    fn hash<H>(&self, state: &mut H)
168    where
169        H: Hasher,
170    {
171        self.to_index().hash(state)
172    }
173}
174
175// Vertex
176
177pub type StaticVertex<N> = N;
178
179// Graph
180
181#[derive(Clone, Debug, PartialEq)]
182pub struct Static<V: Num, K: StaticEdgeKind> {
183    num_vertices: usize,
184    ends: Vec<StaticVertex<V>>,
185    edges: Vec<K::Edge>,
186    edges_start: Vec<usize>,
187}
188
189impl<V: Num, K: StaticEdgeKind> Static<V, K> {
190    fn inc(&self, v: Vertex<Self>) -> &[Edge<Self>] {
191        self.get_inc(v).unwrap()
192    }
193
194    fn get_inc(&self, v: Vertex<Self>) -> Option<&[Edge<Self>]> {
195        let i = V::to_usize(v);
196        self.edges.get(self.edges_start[i]..self.edges_start[i + 1])
197    }
198}
199
200impl<V: Num, K: StaticEdgeKind> WithBuilder for Static<V, K> {
201    type Builder = StaticBuilder<V, K>;
202}
203
204pub struct StaticBuilder<V: Num, K: StaticEdgeKind> {
205    num_vertices: usize,
206    ends: Vec<StaticVertex<V>>,
207    edges: Vec<K::Edge>,
208}
209
210impl<V: Num, K: StaticEdgeKind> Builder for StaticBuilder<V, K> {
211    type Graph = Static<V, K>;
212
213    fn new(num_vertices: usize, num_edges: usize) -> Self {
214        assert!(V::is_valid(num_vertices));
215        StaticBuilder {
216            num_vertices: num_vertices,
217            ends: Vec::with_capacity(2 * num_edges),
218            edges: vec![],
219        }
220    }
221
222    fn add_edge(&mut self, u: usize, v: usize) {
223        self.ends.push(V::from_usize(u));
224        self.ends.push(V::from_usize(v));
225        let e = K::Edge::new_checked((self.ends.len() - 2) / 2).expect("too many edges");
226        self.edges.push(e);
227        if K::Kind::is_undirected() {
228            self.edges.push(e.reverse());
229        }
230    }
231
232    fn finalize(mut self) -> Self::Graph {
233        // TODO: improve test
234        let ends = self.ends;
235        self.edges
236            .sort_by_key(|e| (e.source(&ends), e.target(&ends)));
237
238        let mut starts = Vec::with_capacity(self.num_vertices.checked_add(1).unwrap());
239        let mut last = V::from_usize(self.num_vertices);
240        for (i, e) in self.edges.iter().enumerate() {
241            let s = *e.source(&ends);
242            if s != last {
243                while starts.len() != V::to_usize(s) {
244                    starts.push(i)
245                }
246                assert_eq!(starts.len(), V::to_usize(s));
247                starts.push(i);
248                last = s;
249            }
250        }
251        while starts.len() <= self.num_vertices {
252            starts.push(self.edges.len());
253        }
254
255        Static {
256            num_vertices: self.num_vertices,
257            ends: ends,
258            edges: self.edges,
259            edges_start: starts,
260        }
261    }
262
263    fn finalize_(
264        self,
265    ) -> (
266        Self::Graph,
267        Vec<Vertex<Self::Graph>>,
268        Vec<Edge<Self::Graph>>,
269    ) {
270        let g = self.finalize();
271        let v = vec(g.vertices());
272        let e = vec(g.edges());
273        (g, v, e)
274    }
275}
276
277// Graph implementation
278
279impl<V: Num, K: StaticEdgeKind> WithVertex for Static<V, K> {
280    type Vertex = StaticVertex<V>;
281    type OptionVertex = OptionalMax<StaticVertex<V>>;
282}
283
284impl<V: Num, K: StaticEdgeKind> WithEdge for Static<V, K> {
285    type Kind = K::Kind;
286    type Edge = K::Edge;
287    type OptionEdge = OptionalMax<Self::Edge>;
288
289    fn orientation(&self, _e: Edge<Self>) -> Orientation {
290        K::Kind::orientation()
291    }
292
293    fn source(&self, e: Edge<Self>) -> Vertex<Self> {
294        *e.source(&self.ends)
295    }
296
297    fn target(&self, e: Edge<Self>) -> Vertex<Self> {
298        *e.target(&self.ends)
299    }
300
301    fn get_reverse(&self, e: Edge<Self>) -> Option<Edge<Self>> {
302        if K::Kind::is_undirected() {
303            Some(e.reverse())
304        } else {
305            let (u, v) = self.ends(e);
306            self.get_edge_by_ends(v, u)
307        }
308    }
309}
310
311impl<'a, V: Num, K: StaticEdgeKind> VertexTypes<'a, Static<V, K>> for Static<V, K> {
312    type VertexIter = V::Range;
313    type OutNeighborIter = OutNeighborFromOutEdge<'a, Self, OutEdgeIter<'a, Self>>;
314}
315
316impl<'a, V: Num, K: StaticEdgeKind> EdgeTypes<'a, Static<V, K>> for Static<V, K> {
317    type EdgeIter = Map<Range<usize>, fn(usize) -> K::Edge>;
318    type OutEdgeIter = Cloned<Iter<'a, Edge<Self>>>;
319}
320
321impl<V: Num, K: StaticEdgeKind> VertexList for Static<V, K> {
322    fn num_vertices(&self) -> usize {
323        self.num_vertices
324    }
325
326    fn vertices(&self) -> VertexIter<Self> {
327        V::range(0, self.num_vertices)
328    }
329}
330
331impl<V: Num, K: StaticEdgeKind> EdgeList for Static<V, K> {
332    fn num_edges(&self) -> usize {
333        self.ends.len() / 2
334    }
335
336    fn edges(&self) -> EdgeIter<Self> {
337        (0..self.num_edges()).map(K::Edge::new)
338    }
339
340    fn get_edge_by_ends(&self, u: Vertex<Self>, v: Vertex<Self>) -> Option<Edge<Self>> {
341        self.get_inc(u).and_then(|out_edges| {
342            out_edges
343                .binary_search_by_key(&v, |e| self.target(*e))
344                .ok()
345                .map(|i| out_edges[i])
346        })
347    }
348}
349
350impl<V: Num, K: StaticEdgeKind> Adjacency for Static<V, K> {
351    fn out_neighbors(&self, v: Vertex<Self>) -> OutNeighborIter<Self> {
352        OutNeighborFromOutEdge::new(self, self.out_edges(v))
353    }
354
355    fn out_degree(&self, v: Vertex<Self>) -> usize {
356        self.inc(v).len()
357    }
358}
359
360impl<V: Num, K: StaticEdgeKind> Incidence for Static<V, K> {
361    fn out_edges(&self, v: Vertex<Self>) -> OutEdgeIter<Self> {
362        self.inc(v).iter().cloned()
363    }
364}
365
366// Props
367
368#[derive(Clone, Debug)]
369pub struct SVertexIndexProp;
370
371impl<V: Num> PropGet<StaticVertex<V>> for SVertexIndexProp {
372    type Output = usize;
373
374    fn get(&self, v: StaticVertex<V>) -> usize {
375        v.to_usize()
376    }
377}
378
379impl<V: Num, K: StaticEdgeKind> WithVertexIndexProp for Static<V, K> {
380    type VertexIndexProp = SVertexIndexProp;
381
382    fn vertex_index(&self) -> VertexIndexProp<Self> {
383        SVertexIndexProp
384    }
385}
386
387#[derive(Clone, Debug)]
388pub struct SEdgeIndexProp<K>(PhantomData<K>);
389
390impl<K: StaticEdgeKind> PropGet<K::Edge> for SEdgeIndexProp<K> {
391    type Output = usize;
392
393    fn get(&self, e: K::Edge) -> usize {
394        e.to_index()
395    }
396}
397
398impl<V: Num, K: StaticEdgeKind> WithEdgeIndexProp for Static<V, K> {
399    type EdgeIndexProp = SEdgeIndexProp<K>;
400
401    fn edge_index(&self) -> EdgeIndexProp<Self> {
402        SEdgeIndexProp(PhantomData)
403    }
404}
405
406impl<T, V: Num, K: StaticEdgeKind> WithVertexProp<T> for Static<V, K> {
407    type VertexProp = VecVertexProp<Self, T>;
408}
409
410impl<V: Num, K: StaticEdgeKind> BasicVertexProps for Static<V, K> {}
411
412impl<T, V: Num, K: StaticEdgeKind> WithEdgeProp<T> for Static<V, K> {
413    type EdgeProp = VecEdgeProp<Self, T>;
414}
415
416impl<V: Num, K: StaticEdgeKind> BasicEdgeProps for Static<V, K> {}
417
418impl<V: Num, K: StaticEdgeKind> BasicProps for Static<V, K> {}
419
420// Choose
421
422impl<V: Num, K: StaticEdgeKind> Choose for Static<V, K> {
423    fn choose_vertex<R: Rng>(&self, mut rng: R) -> Option<Vertex<Self>> {
424        if self.num_vertices() == 0 {
425            None
426        } else {
427            Some(V::from_usize(rng.gen_range(0, self.num_vertices())))
428        }
429    }
430
431    fn choose_out_neighbor<R: Rng>(&self, v: Vertex<Self>, rng: R) -> Option<Vertex<Self>> {
432        self.choose_out_edge(v, rng).map(|e| self.target(e))
433    }
434
435    fn choose_edge<R: Rng>(&self, mut rng: R) -> Option<Edge<Self>> {
436        use graphs::common::gen_range_bool;
437        if self.num_edges() == 0 {
438            None
439        } else if K::Kind::is_undirected() {
440            let (i, rev) = gen_range_bool(self.num_edges(), rng).unwrap();
441            let e = K::Edge::new(i);
442            Some(if rev { e.reverse() } else { e })
443        } else {
444            Some(K::Edge::new(rng.gen_range(0, self.num_edges())))
445        }
446    }
447
448    fn choose_out_edge<R: Rng>(&self, v: Vertex<Self>, mut rng: R) -> Option<Edge<Self>> {
449        if self.out_degree(v) == 0 {
450            None
451        } else {
452            self.inc(v)
453                .get(rng.gen_range(0, self.out_degree(v)))
454                .cloned()
455        }
456    }
457}
458
459// Num
460
461pub trait Num: 'static + Eq + Copy + Clone + Debug + Hash + Bounded + Ord {
462    type Range: Iterator<Item = Self>;
463    fn range(a: usize, b: usize) -> Self::Range;
464    fn to_usize(self) -> usize;
465    fn from_usize(v: usize) -> Self;
466    fn is_valid(v: usize) -> bool;
467}
468
469macro_rules! impl_num {
470    ($t:ident) => {
471        impl Num for $t {
472            type Range = Range<$t>;
473
474            #[inline]
475            fn range(a: usize, b: usize) -> Self::Range {
476                Self::from_usize(a)..Self::from_usize(b)
477            }
478
479            #[inline]
480            fn to_usize(self) -> usize {
481                self as usize
482            }
483
484            #[inline]
485            fn from_usize(v: usize) -> Self {
486                v as Self
487            }
488
489            #[inline]
490            fn is_valid(v: usize) -> bool {
491                (v as u64) < (Self::max_value() as u64)
492            }
493        }
494    };
495}
496
497impl_num!(u8);
498impl_num!(u16);
499impl_num!(u32);
500impl_num!(u64);
501impl_num!(usize);
502
503// Tests
504
505#[cfg(test)]
506mod tests {
507    pub use super::{EdgeImpl, StaticDigraph, StaticGraph, StaticUndirectedEdge};
508    pub use prelude::*;
509    use tests::GraphTests;
510
511    macro_rules! test {
512        ($m:ident, $g:ident) => {
513            mod $m {
514                pub use super::*;
515
516                struct Test;
517
518                impl GraphTests for Test {
519                    type G = $g;
520
521                    fn new() -> (Self::G, Vec<Vertex<Self::G>>, Vec<Edge<Self::G>>) {
522                        Self::new_with_builder()
523                    }
524                }
525
526                graph_tests!{Test}
527
528                mod with_builder {
529                    use super::*;
530                    use builder::BuilderTests;
531
532                    struct Test;
533
534                    impl BuilderTests for Test {
535                        type G = StaticGraph;
536                    }
537
538                    graph_builder_tests!{Test}
539                }
540            }
541        };
542    }
543
544    test!(directed, StaticDigraph);
545    test!(undirected, StaticGraph);
546}