acyclic_network/
lib.rs

1extern crate fixedbitset;
2extern crate rand;
3
4mod cycle_detector;
5
6use cycle_detector::CycleDetector;
7use fixedbitset::FixedBitSet;
8use rand::Rng;
9use std::fmt::Debug;
10
11pub trait NodeType: Clone + Debug + Send + Sized + PartialEq + Eq {
12    /// Whether or not the node allows incoming connections
13    fn accept_incoming_links(&self) -> bool;
14
15    /// Whether or not the node allows outgoing connections
16    fn accept_outgoing_links(&self) -> bool;
17}
18
19/// Every node or link contains an external id. This id is
20/// never modified by this library.
21#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
22pub struct ExternalId(pub usize);
23
24/// Newtype wrapping a node index. The node index is
25/// used as an internal index into the node array.
26/// It can become unstable in case of removal of nodes.
27#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
28pub struct NodeIndex(usize);
29
30/// Newtype wrapping a link index.
31#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
32pub struct LinkIndex(usize);
33
34impl NodeIndex {
35    #[inline(always)]
36    pub fn index(&self) -> usize {
37        self.0
38    }
39
40    pub fn new(index: usize) -> Self {
41        NodeIndex(index)
42    }
43}
44
45impl LinkIndex {
46    #[inline(always)]
47    pub fn index(&self) -> usize {
48        self.0
49    }
50}
51
52// Wraps a Link for use in a double linked list
53#[derive(Clone, Debug)]
54struct LinkItem<L, EXTID>
55where
56    L: Copy + Debug + Send + Sized,
57    EXTID: Copy + Debug + Send + Sized + Ord,
58{
59    prev: Option<LinkIndex>,
60    next: Option<LinkIndex>,
61    link: Link<L, EXTID>,
62}
63
64pub struct LinkIter<'a, L, EXTID>
65where
66    L: Copy + Debug + Send + Sized + 'a,
67    EXTID: Copy + Debug + Send + Sized + Ord + 'a,
68{
69    next_link_idx: Option<LinkIndex>,
70    link_array: &'a [LinkItem<L, EXTID>],
71}
72
73impl<'a, L, EXTID> LinkIter<'a, L, EXTID>
74where
75    L: Copy + Debug + Send + Sized + 'a,
76    EXTID: Copy + Debug + Send + Sized + Ord + 'a,
77{
78    fn new(link_idx_opt: Option<LinkIndex>, link_array: &'a [LinkItem<L, EXTID>]) -> Self {
79        LinkIter {
80            next_link_idx: link_idx_opt,
81            link_array: link_array,
82        }
83    }
84}
85
86impl<'a, L, EXTID> Iterator for LinkIter<'a, L, EXTID>
87where
88    L: Copy + Debug + Send + Sized + 'a,
89    EXTID: Copy + Debug + Send + Sized + Ord + 'a,
90{
91    type Item = (LinkIndex, &'a Link<L, EXTID>);
92
93    fn next(&mut self) -> Option<Self::Item> {
94        match self.next_link_idx {
95            Some(idx) => {
96                let item = &self.link_array[idx.index()];
97                self.next_link_idx = item.next;
98                return Some((idx, &item.link));
99            }
100            None => {
101                return None;
102            }
103        }
104    }
105}
106
107pub struct LinkRefIter<'a, N, L, EXTID>
108where
109    N: NodeType + 'a,
110    L: Copy + Debug + Send + Sized + 'a,
111    EXTID: Copy + Debug + Send + Sized + Ord + 'a,
112{
113    next_link_idx: Option<LinkIndex>,
114    network: &'a Network<N, L, EXTID>,
115}
116
117/// A LinkRefItem includes a pointer to the network,
118/// as such, it is read only.
119pub struct LinkRefItem<'a, N, L, EXTID>
120where
121    N: NodeType + 'a,
122    L: Copy + Debug + Send + Sized + 'a,
123    EXTID: Copy + Debug + Send + Sized + Ord + 'a,
124{
125    link: &'a Link<L, EXTID>,
126    network: &'a Network<N, L, EXTID>,
127}
128
129impl<'a, N, L, EXTID> LinkRefItem<'a, N, L, EXTID>
130where
131    N: NodeType + 'a,
132    L: Copy + Debug + Send + Sized + 'a,
133    EXTID: Copy + Debug + Send + Sized + Ord + 'a,
134{
135    pub fn link(&self) -> &Link<L, EXTID> {
136        self.link
137    }
138
139    pub fn network(&self) -> &Network<N, L, EXTID> {
140        self.network
141    }
142
143    pub fn external_link_id(&self) -> EXTID {
144        self.link.external_link_id()
145    }
146
147    pub fn source_node(&self) -> &Node<N, EXTID> {
148        self.network.node(self.link.source_node_idx)
149    }
150
151    pub fn target_node(&self) -> &Node<N, EXTID> {
152        self.network.node(self.link.target_node_idx)
153    }
154
155    pub fn external_source_node_id(&self) -> EXTID {
156        self.source_node().external_node_id()
157    }
158
159    pub fn external_target_node_id(&self) -> EXTID {
160        self.target_node().external_node_id()
161    }
162}
163
164impl<'a, N, L, EXTID> LinkRefIter<'a, N, L, EXTID>
165where
166    N: NodeType + 'a,
167    L: Copy + Debug + Send + Sized + 'a,
168    EXTID: Copy + Debug + Send + Sized + Ord + 'a,
169{
170    fn new(link_idx_opt: Option<LinkIndex>, network: &'a Network<N, L, EXTID>) -> Self {
171        LinkRefIter {
172            next_link_idx: link_idx_opt,
173            network: network,
174        }
175    }
176}
177
178impl<'a, N, L, EXTID> Iterator for LinkRefIter<'a, N, L, EXTID>
179where
180    N: NodeType + 'a,
181    L: Copy + Debug + Send + Sized + 'a,
182    EXTID: Copy + Debug + Send + Sized + Ord + 'a,
183{
184    type Item = (LinkRefItem<'a, N, L, EXTID>);
185
186    fn next(&mut self) -> Option<Self::Item> {
187        match self.next_link_idx {
188            Some(idx) => {
189                let item = &self.network.links[idx.index()];
190                self.next_link_idx = item.next;
191                return Some(LinkRefItem {
192                    link: &item.link,
193                    network: &self.network,
194                });
195            }
196            None => {
197                return None;
198            }
199        }
200    }
201}
202
203#[derive(Clone, Debug)]
204pub struct Link<L, EXTID>
205where
206    L: Copy + Debug + Send + Sized,
207    EXTID: Copy + Debug + Send + Sized + Ord,
208{
209    source_node_idx: NodeIndex,
210    target_node_idx: NodeIndex,
211    weight: L,
212    external_link_id: EXTID,
213
214    // the activeness of a link has no influence on the
215    // cycle detection.
216    active: bool,
217}
218
219impl<L, EXTID> Link<L, EXTID>
220where
221    L: Copy + Debug + Send + Sized,
222    EXTID: Copy + Debug + Send + Sized + Ord,
223{
224    #[inline(always)]
225    pub fn external_link_id(&self) -> EXTID {
226        self.external_link_id
227    }
228
229    #[inline(always)]
230    pub fn source_node_index(&self) -> NodeIndex {
231        self.source_node_idx
232    }
233
234    #[inline(always)]
235    pub fn target_node_index(&self) -> NodeIndex {
236        self.target_node_idx
237    }
238
239    #[inline(always)]
240    pub fn is_active(&self) -> bool {
241        self.active
242    }
243
244    #[inline(always)]
245    pub fn weight(&self) -> L {
246        self.weight
247    }
248
249    #[inline(always)]
250    pub fn set_weight(&mut self, new_weight: L) {
251        self.weight = new_weight;
252    }
253}
254
255#[derive(Clone, Debug)]
256struct List {
257    head: Option<LinkIndex>,
258    tail: Option<LinkIndex>,
259}
260
261impl List {
262    fn empty() -> Self {
263        List {
264            head: None,
265            tail: None,
266        }
267    }
268
269    fn iter<'a, L, EXTID>(&self, link_array: &'a [LinkItem<L, EXTID>]) -> LinkIter<'a, L, EXTID>
270    where
271        L: Copy + Debug + Send + Sized + 'a,
272        EXTID: Copy + Debug + Send + Sized + Ord + 'a,
273    {
274        LinkIter::new(self.head, link_array)
275    }
276}
277
278#[derive(Clone, Debug)]
279pub struct Node<N: NodeType, EXTID: Copy + Debug + Send + Sized + Ord = ExternalId> {
280    node_type: N,
281    external_node_id: EXTID,
282    links: List,
283    // in and out degree counts disabled links!
284    in_degree: u32,
285    out_degree: u32,
286}
287
288impl<N: NodeType, EXTID: Copy + Debug + Send + Sized + Ord> Node<N, EXTID> {
289    pub fn node_type(&self) -> &N {
290        &self.node_type
291    }
292
293    pub fn set_node_type(&mut self, node_type: N) {
294        self.node_type = node_type;
295    }
296
297    pub fn external_node_id(&self) -> EXTID {
298        self.external_node_id
299    }
300
301    pub fn degree(&self) -> usize {
302        self.in_degree as usize + self.out_degree as usize
303    }
304
305    pub fn in_degree(&self) -> u32 {
306        self.in_degree
307    }
308
309    pub fn out_degree(&self) -> u32 {
310        self.out_degree
311    }
312
313    pub fn in_out_degree(&self) -> (u32, u32) {
314        (self.in_degree, self.out_degree)
315    }
316}
317
318/// A directed, acylic network.
319#[derive(Clone, Debug)]
320pub struct Network<
321    N: NodeType,
322    L: Copy + Debug + Send + Sized,
323    EXTID: Copy + Debug + Send + Sized + Ord = ExternalId,
324> {
325    nodes: Vec<Node<N, EXTID>>,
326    links: Vec<LinkItem<L, EXTID>>, // XXX: Rename to link_items
327    link_count: usize,
328    active_link_count: usize,
329}
330
331impl<N: NodeType, L: Copy + Debug + Send + Sized, EXTID: Copy + Debug + Send + Sized + Ord>
332    Network<N, L, EXTID> {
333    pub fn new() -> Network<N, L, EXTID> {
334        Network {
335            nodes: Vec::new(),
336            links: Vec::new(),
337            link_count: 0,
338            active_link_count: 0,
339        }
340    }
341
342    #[inline]
343    pub fn node_count(&self) -> usize {
344        self.nodes.len()
345    }
346
347    #[inline]
348    pub fn link_count(&self) -> usize {
349        self.link_count
350    }
351
352    #[inline(always)]
353    pub fn node(&self, node_idx: NodeIndex) -> &Node<N, EXTID> {
354        &self.nodes[node_idx.index()]
355    }
356
357    #[inline(always)]
358    pub fn node_mut(&mut self, node_idx: NodeIndex) -> &mut Node<N, EXTID> {
359        &mut self.nodes[node_idx.index()]
360    }
361
362    #[inline(always)]
363    fn link_item(&self, link_idx: LinkIndex) -> &LinkItem<L, EXTID> {
364        &self.links[link_idx.index()]
365    }
366
367    #[inline(always)]
368    pub fn link(&self, link_idx: LinkIndex) -> &Link<L, EXTID> {
369        &self.link_item(link_idx).link
370    }
371
372    #[inline(always)]
373    pub fn link_mut(&mut self, link_idx: LinkIndex) -> &mut Link<L, EXTID> {
374        &mut (self.links[link_idx.index()].link)
375    }
376
377    #[inline(always)]
378    pub fn nodes(&self) -> &[Node<N, EXTID>] {
379        &self.nodes
380    }
381
382    #[inline]
383    pub fn each_node_with_index<F>(&self, mut f: F)
384    where
385        F: FnMut(&Node<N, EXTID>, NodeIndex),
386    {
387        for (i, node) in self.nodes.iter().enumerate() {
388            f(node, NodeIndex(i));
389        }
390    }
391
392    #[inline]
393    pub fn link_iter_for_node<'a>(&'a self, node_idx: NodeIndex) -> LinkIter<'a, L, EXTID> {
394        self.node(node_idx).links.iter(&self.links)
395    }
396
397    #[inline]
398    pub fn link_ref_iter_for_node<'a>(
399        &'a self,
400        node_idx: NodeIndex,
401    ) -> LinkRefIter<'a, N, L, EXTID> {
402        LinkRefIter::new(self.node(node_idx).links.head, self)
403    }
404
405    #[inline]
406    pub fn each_active_forward_link_of_node<F>(&self, node_idx: NodeIndex, mut f: F)
407    where
408        F: FnMut(NodeIndex, L),
409    {
410        for (_, link) in self.link_iter_for_node(node_idx) {
411            if link.active {
412                f(link.target_node_idx, link.weight);
413            }
414        }
415    }
416
417    #[inline]
418    pub fn each_link_ref<F>(&self, mut f: F)
419    where
420        F: FnMut(LinkRefItem<N, L, EXTID>),
421    {
422        for link_item in &self.links[..] {
423            f(LinkRefItem {
424                link: &&link_item.link,
425                network: self,
426            });
427        }
428    }
429
430    #[inline]
431    pub fn each_link_mut<F>(&mut self, mut f: F)
432    where
433        F: FnMut(&mut Link<L, EXTID>),
434    {
435        for link_item in &mut self.links[..] {
436            f(&mut link_item.link);
437        }
438    }
439
440    fn inactive_link_count(&self) -> usize {
441        assert!(self.link_count >= self.active_link_count);
442        self.link_count - self.active_link_count
443    }
444
445    /// # Complexity
446    ///
447    /// O(number of links)
448
449    pub fn random_inactive_link_index<R: Rng>(&self, rng: &mut R) -> Option<LinkIndex> {
450        let n = self.inactive_link_count();
451        assert!(n <= self.link_count);
452        if n > 0 {
453            let mut nth_link: usize = rng.gen_range(0, n);
454
455            for node in self.nodes.iter() {
456                for (link_idx, link) in node.links.iter(&self.links) {
457                    if !link.is_active() {
458                        if nth_link > 0 {
459                            nth_link -= 1;
460                        } else {
461                            return Some(link_idx);
462                        }
463                    }
464                }
465            }
466        }
467
468        return None;
469    }
470
471    /// # Complexity
472    ///
473    /// O(number of links)
474
475    pub fn random_active_link_index<R: Rng>(&self, rng: &mut R) -> Option<LinkIndex> {
476        let n = self.active_link_count;
477        assert!(n <= self.link_count);
478        if n > 0 {
479            let mut nth_link: usize = rng.gen_range(0, n);
480
481            for node in self.nodes.iter() {
482                for (link_idx, link) in node.links.iter(&self.links) {
483                    if link.is_active() {
484                        if nth_link > 0 {
485                            nth_link -= 1;
486                        } else {
487                            return Some(link_idx);
488                        }
489                    }
490                }
491            }
492        }
493
494        return None;
495    }
496
497    /// # Complexity
498    ///
499    /// O(1)
500
501    pub fn random_link_index<R: Rng>(&self, rng: &mut R) -> Option<LinkIndex> {
502        let n = self.link_count;
503        if n > 0 {
504            let link_idx: usize = rng.gen_range(0, n);
505            return Some(LinkIndex(link_idx));
506        }
507        return None;
508    }
509
510    /// Removes all outgoing links of node `node_idx`.
511    ///
512    /// XXX: This can be optimized.
513    ///
514    /// # Complexity
515    ///
516    /// O(k), where `k` is the number of edges of `node_idx`.
517
518    pub fn remove_all_outgoing_links_of_node(&mut self, node_idx: NodeIndex) {
519        let n = self.node(node_idx).out_degree as usize;
520
521        for _ in 0..n {
522            let link_index = self.node(node_idx).links.head.unwrap();
523            self.remove_link_at(link_index);
524        }
525        assert!(self.node(node_idx).links.head.is_none());
526        assert!(self.node(node_idx).links.tail.is_none());
527        assert!(self.node(node_idx).out_degree == 0);
528    }
529
530    /// Removes all incoming links to node `node_idx`.
531    ///
532    /// XXX: This can be optimized.
533
534    pub fn remove_all_incoming_links_of_node(&mut self, node_idx: NodeIndex) {
535        let n = self.node(node_idx).in_degree as usize;
536
537        if n == 0 {
538            // If a node does not have any incoming links, we are done!
539            return;
540        }
541
542        // for each node other than `node_idx` try to delete a link to node_idx.
543        for src in 0..self.node_count() {
544            let src_idx = NodeIndex(src);
545            if src_idx != node_idx {
546                if let Some(link_index) = self.find_link_index_exact(src_idx, node_idx) {
547                    self.remove_link_at(link_index);
548                }
549            }
550        }
551
552        assert!(self.node(node_idx).in_degree == 0);
553    }
554
555    /// Removes all links to and from node `node_idx`.
556
557    pub fn remove_all_inout_links_of_node(&mut self, node_idx: NodeIndex) {
558        self.remove_all_outgoing_links_of_node(node_idx);
559        self.remove_all_incoming_links_of_node(node_idx);
560    }
561
562    /// Remove the node with index `node_idx` including
563    /// all incoming and outgoing links.
564    ///
565    /// Moves the last node in the nodes array into the empty
566    /// place and rewires all links. As such, this is a quite
567    /// heavy operation!
568    ///
569    /// # Danger!
570    ///
571    /// The external NodeIndex of the last node is changed!
572    ///
573    /// # Complexity
574    ///
575    /// Worst case O(e), where `e` is the total number of edges in the graph.
576    ///
577    pub fn remove_node(&mut self, node_idx: NodeIndex) {
578        let node_count = self.nodes.len();
579        assert!(node_idx.index() < node_count);
580        assert!(node_count > 0);
581        self.remove_all_inout_links_of_node(node_idx);
582        let last_idx = NodeIndex(node_count - 1);
583        if node_idx == last_idx {
584            // the node is the last! simply pop it off from the end of the array!
585            let _node = self.nodes.pop();
586        } else {
587            // the node is not the last. move the node at `last_idx` into our position.
588            let _node = self.nodes.swap_remove(node_idx.index());
589            // then substitute `last_idx` by `node_idx` in every edge.
590
591            for link_item in self.links.iter_mut() {
592                if link_item.link.target_node_idx == last_idx {
593                    link_item.link.target_node_idx = node_idx;
594                }
595                if link_item.link.source_node_idx == last_idx {
596                    link_item.link.source_node_idx = node_idx;
597                }
598            }
599        }
600        assert!(self.node_count() == node_count - 1);
601    }
602
603    /// Adds a new node to the network with type `node_type` and the associated
604    /// id `external_node_id`. The `external_node_id` is stored in the node and
605    /// can be retrieved later on.
606    ///
607    pub fn add_node(&mut self, node_type: N, external_node_id: EXTID) -> NodeIndex {
608        let node_idx = NodeIndex(self.nodes.len());
609        self.nodes.push(Node {
610            node_type: node_type,
611            external_node_id: external_node_id,
612            links: List::empty(),
613            in_degree: 0,
614            out_degree: 0,
615        });
616        return node_idx;
617    }
618
619    /// Returns a random link between two unconnected nodes, which would not
620    /// introduce
621    /// a cycle. Return None is no such exists.
622    pub fn find_random_unconnected_link_no_cycle<R: Rng>(
623        &self,
624        rng: &mut R,
625    ) -> Option<(NodeIndex, NodeIndex)> {
626        let n = self.nodes.len();
627
628        let idx = &|i, j| i * n + j;
629
630        let mut adj_matrix = FixedBitSet::with_capacity(n * n);
631
632        // Build up a binary, undirected adjacency matrix of the graph.
633        // Every unset bit in the adj_matrix will be a potential link.
634        for (i, node) in self.nodes.iter().enumerate() {
635            for (_, link) in node.links.iter(&self.links) {
636                let j = link.target_node_idx.index();
637                adj_matrix.insert(idx(i, j));
638                // include the link of reverse direction, because this would
639                // create a cycle anyway.
640                adj_matrix.insert(idx(j, i));
641            }
642        }
643
644        let adj_matrix = adj_matrix; // make immutable
645
646        // We now test all potential links of every node in the graph, if it would
647        // introduce a cycle. For that, we shuffle the node indices (`node_order`).
648        // in random order.
649        // XXX: Remove deleted nodes
650        let mut node_order: Vec<_> = (0..n).into_iter().collect();
651        let mut edge_order: Vec<_> = (0..n).into_iter().collect();
652        rng.shuffle(&mut node_order);
653
654        let node_order = node_order; // make immutable
655
656        let mut cycler = CycleDetector::new(self);
657        for &i in &node_order {
658            rng.shuffle(&mut edge_order);
659            for &j in &edge_order {
660                if i != j && !adj_matrix.contains(idx(i, j)) {
661                    // The link (i, j) neither is reflexive, nor exists.
662                    let ni = NodeIndex(i);
663                    let nj = NodeIndex(j);
664                    if self.valid_link(ni, nj).is_ok() && !cycler.link_would_cycle(ni, nj) {
665                        // If the link is valid and does not create a cycle, we are done!
666                        return Some((ni, nj));
667                    }
668                }
669            }
670        }
671
672        return None;
673    }
674
675    /// Returns true if the introduction of this directed link would lead towards a
676    /// cycle.
677    pub fn link_would_cycle(&self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
678        if source_node_idx == target_node_idx {
679            return true;
680        }
681
682        CycleDetector::new(self).link_would_cycle(source_node_idx, target_node_idx)
683    }
684
685    // Check if the link is valid. Doesn't check for cycles.
686    pub fn valid_link(
687        &self,
688        source_node_idx: NodeIndex,
689        target_node_idx: NodeIndex,
690    ) -> Result<(), &'static str> {
691        if source_node_idx == target_node_idx {
692            return Err("Loops are not allowed");
693        }
694
695        if !self.nodes[source_node_idx.index()]
696            .node_type
697            .accept_outgoing_links()
698        {
699            return Err("Node does not allow outgoing links");
700        }
701
702        if !self.nodes[target_node_idx.index()]
703            .node_type
704            .accept_incoming_links()
705        {
706            return Err("Node does not allow incoming links");
707        }
708
709        Ok(())
710    }
711
712    fn allocate_link_item(&mut self, link_item: LinkItem<L, EXTID>) -> LinkIndex {
713        let new_link_idx = LinkIndex(self.links.len());
714        self.links.push(link_item);
715        return new_link_idx;
716    }
717
718    pub fn disable_link_index(&mut self, link_idx: LinkIndex) -> bool {
719        if self.link(link_idx).is_active() {
720            self.active_link_count -= 1;
721            self.link_mut(link_idx).active = false;
722            return true;
723        } else {
724            return false;
725        }
726    }
727
728    pub fn enable_link_index(&mut self, link_idx: LinkIndex) -> bool {
729        if !self.link(link_idx).is_active() {
730            self.active_link_count += 1;
731            self.link_mut(link_idx).active = true;
732            return true;
733        } else {
734            return false;
735        }
736    }
737
738    pub fn disable_link(&mut self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
739        if let Some(link_idx) = self.find_link_index_exact(source_node_idx, target_node_idx) {
740            return self.disable_link_index(link_idx);
741        }
742        return false;
743    }
744
745    pub fn enable_link(&mut self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
746        if let Some(link_idx) = self.find_link_index_exact(source_node_idx, target_node_idx) {
747            return self.enable_link_index(link_idx);
748        }
749        return false;
750    }
751
752    pub fn first_link_of_node(&self, node_idx: NodeIndex) -> Option<&Link<L, EXTID>> {
753        self.node(node_idx)
754            .links
755            .head
756            .map(|link_idx| self.link(link_idx))
757    }
758
759    pub fn last_link_of_node(&self, node_idx: NodeIndex) -> Option<&Link<L, EXTID>> {
760        self.node(node_idx)
761            .links
762            .tail
763            .map(|link_idx| self.link(link_idx))
764    }
765
766    fn append(&mut self, node_idx: NodeIndex, link: Link<L, EXTID>) -> LinkIndex {
767        match (
768            self.node(node_idx).links.head,
769            self.node(node_idx).links.tail,
770        ) {
771            (None, None) => {
772                // append onto empty list
773                let new_link_idx = self.allocate_link_item(LinkItem {
774                    link: link,
775                    prev: None,
776                    next: None,
777                });
778                self.node_mut(node_idx).links = List {
779                    head: Some(new_link_idx),
780                    tail: Some(new_link_idx),
781                };
782                return new_link_idx;
783            }
784            (Some(_), Some(tail)) => {
785                let new_link_idx = self.allocate_link_item(LinkItem {
786                    link: link,
787                    prev: Some(tail),
788                    next: None,
789                });
790                assert!(self.links[tail.index()].next == None);
791                self.links[tail.index()].next = Some(new_link_idx);
792                self.node_mut(node_idx).links.tail = Some(new_link_idx);
793                return new_link_idx;
794            }
795            _ => panic!(),
796        }
797    }
798
799    fn prepend(&mut self, node_idx: NodeIndex, link: Link<L, EXTID>) -> LinkIndex {
800        match (
801            self.node(node_idx).links.head,
802            self.node(node_idx).links.tail,
803        ) {
804            (None, None) => {
805                // prepend to empty list. same as append
806                let new_link_idx = self.allocate_link_item(LinkItem {
807                    link: link,
808                    prev: None,
809                    next: None,
810                });
811                self.node_mut(node_idx).links = List {
812                    head: Some(new_link_idx),
813                    tail: Some(new_link_idx),
814                };
815                return new_link_idx;
816            }
817            (Some(head), Some(_tail)) => {
818                let new_link_idx = self.allocate_link_item(LinkItem {
819                    link: link,
820                    prev: None,
821                    next: Some(head),
822                });
823                assert!(self.links[head.index()].prev == None);
824                self.links[head.index()].prev = Some(new_link_idx);
825                self.node_mut(node_idx).links.head = Some(new_link_idx);
826                return new_link_idx;
827            }
828            _ => panic!(),
829        }
830    }
831
832    pub fn add_link(
833        &mut self,
834        source_node_idx: NodeIndex,
835        target_node_idx: NodeIndex,
836        weight: L,
837        external_link_id: EXTID,
838    ) -> LinkIndex {
839        self.add_link_with_active(
840            source_node_idx,
841            target_node_idx,
842            weight,
843            external_link_id,
844            true,
845        )
846    }
847
848    // This will destroy the ordering relation of links.
849    // Do not mix with `add_link` or `add_link_with_active`.
850
851    pub fn add_link_unordered(
852        &mut self,
853        source_node_idx: NodeIndex,
854        target_node_idx: NodeIndex,
855        weight: L,
856        external_link_id: EXTID,
857    ) -> LinkIndex {
858        if let Err(err) = self.valid_link(source_node_idx, target_node_idx) {
859            panic!(err);
860        }
861
862        self.link_count += 1;
863        self.active_link_count += 1;
864
865        self.node_mut(source_node_idx).out_degree += 1;
866        self.node_mut(target_node_idx).in_degree += 1;
867
868        let link = Link {
869            source_node_idx: source_node_idx,
870            target_node_idx: target_node_idx,
871            external_link_id: external_link_id,
872            weight: weight,
873            active: true,
874        };
875
876        return self.append(source_node_idx, link);
877    }
878
879    // Note: Doesn't check for cycles (except in the simple reflexive case).
880    // Note that we keep the list of links sorted according to it's
881    // external_link_id.
882    // XXX: Need test cases.
883    pub fn add_link_with_active(
884        &mut self,
885        source_node_idx: NodeIndex,
886        target_node_idx: NodeIndex,
887        weight: L,
888        external_link_id: EXTID,
889        active: bool,
890    ) -> LinkIndex {
891        if let Err(err) = self.valid_link(source_node_idx, target_node_idx) {
892            panic!(err);
893        }
894
895        self.link_count += 1;
896        if active {
897            self.active_link_count += 1;
898        }
899        self.node_mut(source_node_idx).out_degree += 1;
900        self.node_mut(target_node_idx).in_degree += 1;
901
902        let link = Link {
903            source_node_idx: source_node_idx,
904            target_node_idx: target_node_idx,
905            external_link_id: external_link_id,
906            weight: weight,
907            active: active,
908        };
909
910        match self.find_link_index_insert_before(source_node_idx, target_node_idx, external_link_id)
911        {
912            None => {
913                if let Some(tail) = self.node(source_node_idx).links.tail {
914                    // check if last element is equal
915                    if self.link(tail).target_node_idx == target_node_idx {
916                        assert!(self.link(tail).external_link_id == external_link_id);
917                        panic!("Duplicate link");
918                    }
919                }
920                // append at end.
921                return self.append(source_node_idx, link);
922            }
923            Some(idx) => {
924                match self.link_item(idx).prev {
925                    None => {
926                        return self.prepend(source_node_idx, link);
927                    }
928                    Some(insert_after) => {
929                        // check if previous element is not equal
930                        if self.link(insert_after).target_node_idx == target_node_idx {
931                            assert!(self.link(insert_after).external_link_id == external_link_id);
932                            panic!("Duplicate link");
933                        }
934
935                        let new_link_idx = self.allocate_link_item(LinkItem {
936                            link: link,
937                            prev: Some(insert_after),
938                            next: Some(idx),
939                        });
940
941                        self.links[insert_after.index()].next = Some(new_link_idx);
942                        self.links[idx.index()].prev = Some(new_link_idx);
943
944                        return new_link_idx;
945                    }
946                }
947            }
948        }
949    }
950
951    // Returns the index of the first element whoose external link id >
952    // `external_link_id`.
953    fn find_link_index_insert_before(
954        &self,
955        source_node_idx: NodeIndex,
956        _target_node_idx: NodeIndex,
957        external_link_id: EXTID,
958    ) -> Option<LinkIndex> {
959        // the links are sorted according to their external link id.
960        let mut link_iter = self.link_iter_for_node(source_node_idx);
961        for (idx, link) in &mut link_iter {
962            if link.external_link_id() > external_link_id {
963                return Some(idx);
964            }
965        }
966        return None;
967    }
968
969    pub fn has_link(&self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
970        self.find_link_index_exact(source_node_idx, target_node_idx)
971            .is_some()
972    }
973
974    fn find_link_index_exact(
975        &self,
976        source_node_idx: NodeIndex,
977        target_node_idx: NodeIndex,
978    ) -> Option<LinkIndex> {
979        for (link_idx, link) in self.link_iter_for_node(source_node_idx) {
980            // We found the node we are looking for.
981            if link.target_node_idx == target_node_idx {
982                return Some(link_idx);
983            }
984        }
985        return None;
986    }
987
988    /// Remove the link at index `link_index`.
989    pub fn remove_link_at(&mut self, link_index: LinkIndex) {
990        let found_idx = link_index;
991        let source_node_idx = self.link(found_idx).source_node_idx;
992        let target_node_idx = self.link(found_idx).target_node_idx;
993
994        if self.link(found_idx).is_active() {
995            self.active_link_count -= 1;
996        }
997
998        // remove item from chain
999
1000        match (
1001            self.link_item(found_idx).prev,
1002            self.link_item(found_idx).next,
1003        ) {
1004            (None, None) => {
1005                // Item is the only element of the list.
1006                assert!(self.node(source_node_idx).links.head == Some(found_idx));
1007                assert!(self.node(source_node_idx).links.tail == Some(found_idx));
1008                self.node_mut(source_node_idx).links = List::empty();
1009            }
1010
1011            (None, Some(next)) => {
1012                // Item is the first element in the list, followed by some other element.
1013                assert!(self.links[next.index()].prev == Some(found_idx));
1014                assert!(self.node(source_node_idx).links.head == Some(found_idx));
1015                assert!(self.node(source_node_idx).links.tail != Some(found_idx));
1016                self.node_mut(source_node_idx).links.head = Some(next);
1017                self.links[next.index()].prev = None;
1018            }
1019
1020            (Some(prev), None) => {
1021                // Item is the last element of the list, preceded by some other element.
1022                assert!(self.links[prev.index()].next == Some(found_idx));
1023                assert!(self.node(source_node_idx).links.tail == Some(found_idx));
1024                assert!(self.node(source_node_idx).links.head != Some(found_idx));
1025
1026                // make the previous element the new tail
1027                self.node_mut(source_node_idx).links.tail = Some(prev);
1028                self.links[prev.index()].next = None;
1029            }
1030
1031            (Some(prev), Some(next)) => {
1032                // Item is somewhere in the middle of the list. We don't have to
1033                // update the head or tail pointers.
1034                assert!(self.node(source_node_idx).links.head != Some(found_idx));
1035                assert!(self.node(source_node_idx).links.tail != Some(found_idx));
1036
1037                assert!(self.links[prev.index()].next == Some(found_idx));
1038                assert!(self.links[next.index()].prev == Some(found_idx));
1039
1040                self.links[prev.index()].next = Some(next);
1041                self.links[next.index()].prev = Some(prev);
1042            }
1043        }
1044
1045        self.links[found_idx.index()].next = None;
1046        self.links[found_idx.index()].prev = None;
1047
1048        // swap the item with the last one.
1049        let old_idx = LinkIndex(self.links.len() - 1);
1050
1051        if found_idx == old_idx {
1052            // if we are the last element, we can just pop it
1053            let old = self.links.pop().unwrap();
1054            debug_assert!(old.link.source_node_idx == source_node_idx);
1055            debug_assert!(old.link.target_node_idx == target_node_idx);
1056        } else {
1057            let old = self.links.swap_remove(found_idx.index());
1058            debug_assert!(old.link.source_node_idx == source_node_idx);
1059            debug_assert!(old.link.target_node_idx == target_node_idx);
1060
1061            // We have to change the linking of the newly at position `found_idx` placed
1062            // element.
1063            let new_idx = found_idx;
1064            // change the next pointer of the previous element
1065            let new_source_node_idx = self.link(new_idx).source_node_idx;
1066
1067            match (self.link_item(new_idx).prev, self.link_item(new_idx).next) {
1068                (None, None) => {
1069                    // the moved element was the only element in the list.
1070                    assert!(self.node(new_source_node_idx).links.head == Some(old_idx));
1071                    assert!(self.node(new_source_node_idx).links.tail == Some(old_idx));
1072
1073                    // Update both head and tail to the new element index.
1074                    self.node_mut(new_source_node_idx).links = List {
1075                        head: Some(new_idx),
1076                        tail: Some(new_idx),
1077                    };
1078                }
1079
1080                (None, Some(next)) => {
1081                    // Item is the first element in the list, followed by some other element.
1082                    assert!(self.links[next.index()].prev == Some(old_idx));
1083                    assert!(self.node(new_source_node_idx).links.head == Some(old_idx));
1084                    assert!(self.node(new_source_node_idx).links.tail != Some(old_idx));
1085                    self.node_mut(new_source_node_idx).links.head = Some(new_idx);
1086                    self.links[next.index()].prev = Some(new_idx);
1087                }
1088
1089                (Some(prev), None) => {
1090                    // Item is the last element of the list, preceded by some other element.
1091                    assert!(self.links[prev.index()].next == Some(old_idx));
1092                    assert!(self.node(new_source_node_idx).links.tail == Some(old_idx));
1093                    assert!(self.node(new_source_node_idx).links.head != Some(old_idx));
1094
1095                    // make the previous element the new tail
1096                    self.node_mut(new_source_node_idx).links.tail = Some(new_idx);
1097                    self.links[prev.index()].next = Some(new_idx);
1098                }
1099
1100                (Some(prev), Some(next)) => {
1101                    // Item is somewhere in the middle of the list. We don't have to
1102                    // update the head or tail pointers.
1103                    assert!(self.node(new_source_node_idx).links.head != Some(old_idx));
1104                    assert!(self.node(new_source_node_idx).links.tail != Some(old_idx));
1105
1106                    assert!(self.links[prev.index()].next == Some(old_idx));
1107                    assert!(self.links[next.index()].prev == Some(old_idx));
1108
1109                    self.links[prev.index()].next = Some(new_idx);
1110                    self.links[next.index()].prev = Some(new_idx);
1111                }
1112            }
1113        }
1114
1115        assert!(self.node(source_node_idx).out_degree > 0);
1116        assert!(self.node(target_node_idx).in_degree > 0);
1117        self.node_mut(source_node_idx).out_degree -= 1;
1118        self.node_mut(target_node_idx).in_degree -= 1;
1119        self.link_count -= 1;
1120    }
1121
1122    /// Remove the first link that matches `source_node_idx` and `target_node_idx`.
1123    /// XXX
1124    pub fn remove_link(&mut self, source_node_idx: NodeIndex, target_node_idx: NodeIndex) -> bool {
1125        if let Some(found_idx) = self.find_link_index_exact(source_node_idx, target_node_idx) {
1126            debug_assert!(self.link(found_idx).source_node_idx == source_node_idx);
1127            debug_assert!(self.link(found_idx).target_node_idx == target_node_idx);
1128            self.remove_link_at(found_idx);
1129            return true;
1130        } else {
1131            // link was not found
1132            return false;
1133        }
1134    }
1135}
1136
1137#[cfg(test)]
1138mod tests {
1139    use rand;
1140    use super::{ExternalId, Network, NodeIndex, NodeType};
1141
1142    #[derive(Clone, Debug, PartialEq, Eq)]
1143    enum NodeT {
1144        Input,
1145        Hidden,
1146        Output,
1147    }
1148
1149    impl NodeType for NodeT {
1150        fn accept_incoming_links(&self) -> bool {
1151            match *self {
1152                NodeT::Input => false,
1153                _ => true,
1154            }
1155        }
1156        fn accept_outgoing_links(&self) -> bool {
1157            match *self {
1158                NodeT::Output => false,
1159                _ => true,
1160            }
1161        }
1162    }
1163
1164    #[test]
1165    fn test_cycle() {
1166        let mut g = Network::new();
1167        let i1 = g.add_node(NodeT::Input, ExternalId(1));
1168        let h1 = g.add_node(NodeT::Hidden, ExternalId(2));
1169        let h2 = g.add_node(NodeT::Hidden, ExternalId(3));
1170        assert_eq!(true, g.valid_link(i1, i1).is_err());
1171        assert_eq!(true, g.valid_link(h1, h1).is_err());
1172
1173        assert_eq!(true, g.valid_link(h1, i1).is_err());
1174        assert_eq!(Ok(()), g.valid_link(i1, h1));
1175        assert_eq!(Ok(()), g.valid_link(i1, h2));
1176        assert_eq!(Ok(()), g.valid_link(h1, h2));
1177
1178        assert_eq!((0, 0), g.node(i1).in_out_degree());
1179        assert_eq!((0, 0), g.node(h1).in_out_degree());
1180        assert_eq!((0, 0), g.node(h2).in_out_degree());
1181
1182        g.add_link(i1, h1, 0.0, ExternalId(1));
1183        assert_eq!((0, 1), g.node(i1).in_out_degree());
1184        assert_eq!((1, 0), g.node(h1).in_out_degree());
1185        assert_eq!((0, 0), g.node(h2).in_out_degree());
1186
1187        assert_eq!(true, g.link_would_cycle(h1, i1));
1188        assert_eq!(false, g.link_would_cycle(i1, h1));
1189        assert_eq!(false, g.link_would_cycle(i1, h2));
1190        assert_eq!(true, g.link_would_cycle(i1, i1));
1191        assert_eq!(false, g.link_would_cycle(h1, h2));
1192        assert_eq!(false, g.link_would_cycle(h2, h1));
1193        assert_eq!(false, g.link_would_cycle(h2, i1));
1194
1195        g.add_link(h1, h2, 0.0, ExternalId(2));
1196        assert_eq!((0, 1), g.node(i1).in_out_degree());
1197        assert_eq!((1, 1), g.node(h1).in_out_degree());
1198        assert_eq!((1, 0), g.node(h2).in_out_degree());
1199
1200        assert_eq!(true, g.link_would_cycle(h2, i1));
1201        assert_eq!(true, g.link_would_cycle(h1, i1));
1202        assert_eq!(true, g.link_would_cycle(h2, h1));
1203        assert_eq!(false, g.link_would_cycle(i1, h2));
1204    }
1205
1206    #[test]
1207    fn test_find_random_unconnected_link_no_cycle() {
1208        let mut g = Network::new();
1209        let i1 = g.add_node(NodeT::Input, ExternalId(1));
1210        let o1 = g.add_node(NodeT::Output, ExternalId(2));
1211        let o2 = g.add_node(NodeT::Output, ExternalId(3));
1212
1213        let mut rng = rand::thread_rng();
1214
1215        let link = g.find_random_unconnected_link_no_cycle(&mut rng);
1216        assert_eq!(true, link.is_some());
1217        let l = link.unwrap();
1218        assert!((i1, o1) == l || (i1, o2) == l);
1219
1220        g.add_link(i1, o2, 0.0, ExternalId(1));
1221        let link = g.find_random_unconnected_link_no_cycle(&mut rng);
1222        assert_eq!(true, link.is_some());
1223        assert_eq!((i1, o1), link.unwrap());
1224
1225        g.add_link(i1, o1, 0.0, ExternalId(2));
1226        let link = g.find_random_unconnected_link_no_cycle(&mut rng);
1227        assert_eq!(false, link.is_some());
1228    }
1229
1230    #[test]
1231    fn test_remove_link() {
1232        let mut g = Network::new();
1233        let i1 = g.add_node(NodeT::Input, ExternalId(1));
1234        let h1 = g.add_node(NodeT::Hidden, ExternalId(2));
1235        let h2 = g.add_node(NodeT::Hidden, ExternalId(3));
1236
1237        g.add_link(i1, h1, 0.0, ExternalId(2));
1238        g.add_link(i1, h2, 0.0, ExternalId(1));
1239
1240        assert_eq!(
1241            ExternalId(1),
1242            g.first_link_of_node(i1).unwrap().external_link_id()
1243        );
1244        assert_eq!(
1245            ExternalId(2),
1246            g.last_link_of_node(i1).unwrap().external_link_id()
1247        );
1248
1249        assert_eq!(2, g.node(i1).out_degree());
1250        assert_eq!(1, g.node(h1).in_degree());
1251        assert_eq!(1, g.node(h2).in_degree());
1252        assert_eq!(2, g.link_count());
1253
1254        assert_eq!(true, g.remove_link(i1, h1));
1255        assert_eq!(1, g.node(i1).out_degree());
1256        assert_eq!(0, g.node(h1).in_degree());
1257        assert_eq!(1, g.node(h2).in_degree());
1258        assert_eq!(1, g.link_count());
1259
1260        assert_eq!(
1261            ExternalId(1),
1262            g.first_link_of_node(i1).unwrap().external_link_id()
1263        );
1264        assert_eq!(
1265            ExternalId(1),
1266            g.last_link_of_node(i1).unwrap().external_link_id()
1267        );
1268
1269        assert_eq!(false, g.remove_link(i1, h1));
1270        assert_eq!(1, g.node(i1).out_degree());
1271        assert_eq!(0, g.node(h1).in_degree());
1272        assert_eq!(1, g.node(h2).in_degree());
1273        assert_eq!(1, g.link_count());
1274
1275        assert_eq!(
1276            ExternalId(1),
1277            g.first_link_of_node(i1).unwrap().external_link_id()
1278        );
1279        assert_eq!(
1280            ExternalId(1),
1281            g.last_link_of_node(i1).unwrap().external_link_id()
1282        );
1283
1284        assert_eq!(true, g.remove_link(i1, h2));
1285        assert_eq!(0, g.node(i1).out_degree());
1286        assert_eq!(0, g.node(h1).in_degree());
1287        assert_eq!(0, g.node(h2).in_degree());
1288        assert_eq!(0, g.link_count());
1289
1290        assert!(g.first_link_of_node(i1).is_none());
1291        assert!(g.last_link_of_node(i1).is_none());
1292
1293        // XXX: test for sort order
1294    }
1295
1296    #[test]
1297    fn test_add_remove_link_unordered() {
1298        let mut g = Network::new();
1299        let i1 = g.add_node(NodeT::Input, ());
1300        let h1 = g.add_node(NodeT::Hidden, ());
1301        let h2 = g.add_node(NodeT::Hidden, ());
1302
1303        g.add_link_unordered(i1, h1, 0.0, ());
1304        g.add_link_unordered(i1, h2, 0.0, ());
1305
1306        assert_eq!(h1, g.first_link_of_node(i1).unwrap().target_node_idx);
1307        assert_eq!(h2, g.last_link_of_node(i1).unwrap().target_node_idx);
1308
1309        assert_eq!(2, g.node(i1).out_degree());
1310        assert_eq!(1, g.node(h1).in_degree());
1311        assert_eq!(1, g.node(h2).in_degree());
1312        assert_eq!(2, g.link_count());
1313
1314        assert_eq!(true, g.remove_link(i1, h1));
1315        assert_eq!(1, g.node(i1).out_degree());
1316        assert_eq!(0, g.node(h1).in_degree());
1317        assert_eq!(1, g.node(h2).in_degree());
1318        assert_eq!(1, g.link_count());
1319
1320        assert_eq!(h2, g.first_link_of_node(i1).unwrap().target_node_idx);
1321        assert_eq!(h2, g.last_link_of_node(i1).unwrap().target_node_idx);
1322
1323        assert_eq!(false, g.remove_link(i1, h1));
1324        assert_eq!(1, g.node(i1).out_degree());
1325        assert_eq!(0, g.node(h1).in_degree());
1326        assert_eq!(1, g.node(h2).in_degree());
1327        assert_eq!(1, g.link_count());
1328
1329        assert_eq!(h2, g.first_link_of_node(i1).unwrap().target_node_idx);
1330        assert_eq!(h2, g.last_link_of_node(i1).unwrap().target_node_idx);
1331
1332        assert_eq!(true, g.remove_link(i1, h2));
1333        assert_eq!(0, g.node(i1).out_degree());
1334        assert_eq!(0, g.node(h1).in_degree());
1335        assert_eq!(0, g.node(h2).in_degree());
1336        assert_eq!(0, g.link_count());
1337
1338        assert!(g.first_link_of_node(i1).is_none());
1339        assert!(g.last_link_of_node(i1).is_none());
1340    }
1341
1342    #[test]
1343    fn test_remove_all_outgoing_links() {
1344        let mut g = Network::new();
1345        let i1 = g.add_node(NodeT::Input, ());
1346        let h1 = g.add_node(NodeT::Hidden, ());
1347        let h2 = g.add_node(NodeT::Hidden, ());
1348        let o1 = g.add_node(NodeT::Output, ());
1349
1350        g.add_link_unordered(i1, h1, 0.0, ());
1351        g.add_link_unordered(i1, h2, 0.0, ());
1352        g.add_link_unordered(h1, o1, 0.0, ());
1353        g.add_link_unordered(h2, o1, 0.0, ());
1354
1355        assert_eq!(2, g.node(i1).out_degree());
1356        assert_eq!(1, g.node(h1).in_degree());
1357        assert_eq!(1, g.node(h2).in_degree());
1358        assert_eq!(1, g.node(h1).out_degree());
1359        assert_eq!(1, g.node(h2).out_degree());
1360        assert_eq!(2, g.node(o1).in_degree());
1361        assert_eq!(0, g.node(o1).out_degree());
1362        assert_eq!(4, g.link_count());
1363
1364        g.remove_all_outgoing_links_of_node(i1);
1365
1366        assert!(g.first_link_of_node(i1).is_none());
1367        assert!(g.last_link_of_node(i1).is_none());
1368
1369        assert_eq!(0, g.node(i1).out_degree());
1370        assert_eq!(0, g.node(h1).in_degree());
1371        assert_eq!(0, g.node(h2).in_degree());
1372        assert_eq!(1, g.node(h1).out_degree());
1373        assert_eq!(1, g.node(h2).out_degree());
1374        assert_eq!(2, g.node(o1).in_degree());
1375        assert_eq!(0, g.node(o1).out_degree());
1376        assert_eq!(2, g.link_count());
1377    }
1378
1379    #[test]
1380    fn test_remove_all_incoming_links() {
1381        let mut g = Network::new();
1382        let i1 = g.add_node(NodeT::Input, ());
1383        let h1 = g.add_node(NodeT::Hidden, ());
1384        let h2 = g.add_node(NodeT::Hidden, ());
1385        let o1 = g.add_node(NodeT::Output, ());
1386
1387        g.add_link_unordered(i1, h1, 0.0, ());
1388        g.add_link_unordered(i1, h2, 0.0, ());
1389        g.add_link_unordered(h1, o1, 0.0, ());
1390        g.add_link_unordered(h2, o1, 0.0, ());
1391
1392        assert_eq!(2, g.node(i1).out_degree());
1393        assert_eq!(1, g.node(h1).in_degree());
1394        assert_eq!(1, g.node(h2).in_degree());
1395        assert_eq!(1, g.node(h1).out_degree());
1396        assert_eq!(1, g.node(h2).out_degree());
1397        assert_eq!(2, g.node(o1).in_degree());
1398        assert_eq!(0, g.node(o1).out_degree());
1399        assert_eq!(4, g.link_count());
1400        assert!(g.first_link_of_node(i1).is_some());
1401        assert!(g.last_link_of_node(i1).is_some());
1402
1403        g.remove_all_incoming_links_of_node(i1);
1404
1405        assert_eq!(2, g.node(i1).out_degree());
1406        assert_eq!(1, g.node(h1).in_degree());
1407        assert_eq!(1, g.node(h2).in_degree());
1408        assert_eq!(1, g.node(h1).out_degree());
1409        assert_eq!(1, g.node(h2).out_degree());
1410        assert_eq!(2, g.node(o1).in_degree());
1411        assert_eq!(0, g.node(o1).out_degree());
1412        assert_eq!(4, g.link_count());
1413        assert!(g.first_link_of_node(i1).is_some());
1414        assert!(g.last_link_of_node(i1).is_some());
1415
1416        g.remove_all_incoming_links_of_node(h1);
1417
1418        assert_eq!(1, g.node(i1).out_degree());
1419        assert_eq!(0, g.node(h1).in_degree());
1420        assert_eq!(1, g.node(h2).in_degree());
1421        assert_eq!(1, g.node(h1).out_degree());
1422        assert_eq!(1, g.node(h2).out_degree());
1423        assert_eq!(2, g.node(o1).in_degree());
1424        assert_eq!(0, g.node(o1).out_degree());
1425        assert_eq!(3, g.link_count());
1426        assert!(g.first_link_of_node(i1).is_some());
1427        assert!(g.last_link_of_node(i1).is_some());
1428
1429        g.remove_all_incoming_links_of_node(h2);
1430
1431        assert_eq!(0, g.node(i1).out_degree());
1432        assert_eq!(0, g.node(h1).in_degree());
1433        assert_eq!(0, g.node(h2).in_degree());
1434        assert_eq!(1, g.node(h1).out_degree());
1435        assert_eq!(1, g.node(h2).out_degree());
1436        assert_eq!(2, g.node(o1).in_degree());
1437        assert_eq!(0, g.node(o1).out_degree());
1438        assert_eq!(2, g.link_count());
1439        assert!(g.first_link_of_node(i1).is_none());
1440        assert!(g.last_link_of_node(i1).is_none());
1441    }
1442
1443    #[test]
1444    fn test_remove_all_inout_links() {
1445        let mut g = Network::new();
1446        let i1 = g.add_node(NodeT::Input, ());
1447        let h1 = g.add_node(NodeT::Hidden, ());
1448        let h2 = g.add_node(NodeT::Hidden, ());
1449        let o1 = g.add_node(NodeT::Output, ());
1450
1451        g.add_link_unordered(i1, h1, 0.0, ());
1452        g.add_link_unordered(i1, h2, 0.0, ());
1453        g.add_link_unordered(h1, o1, 0.0, ());
1454        g.add_link_unordered(h2, o1, 0.0, ());
1455
1456        assert_eq!(2, g.node(i1).out_degree());
1457        assert_eq!(1, g.node(h1).in_degree());
1458        assert_eq!(1, g.node(h2).in_degree());
1459        assert_eq!(1, g.node(h1).out_degree());
1460        assert_eq!(1, g.node(h2).out_degree());
1461        assert_eq!(2, g.node(o1).in_degree());
1462        assert_eq!(0, g.node(o1).out_degree());
1463        assert_eq!(4, g.link_count());
1464
1465        g.remove_all_inout_links_of_node(i1);
1466
1467        assert!(g.first_link_of_node(i1).is_none());
1468        assert!(g.last_link_of_node(i1).is_none());
1469
1470        assert_eq!(0, g.node(i1).out_degree());
1471        assert_eq!(0, g.node(h1).in_degree());
1472        assert_eq!(0, g.node(h2).in_degree());
1473        assert_eq!(1, g.node(h1).out_degree());
1474        assert_eq!(1, g.node(h2).out_degree());
1475        assert_eq!(2, g.node(o1).in_degree());
1476        assert_eq!(0, g.node(o1).out_degree());
1477        assert_eq!(2, g.link_count());
1478
1479        g.remove_all_inout_links_of_node(h1);
1480
1481        assert_eq!(0, g.node(i1).out_degree());
1482        assert_eq!(0, g.node(h1).in_degree());
1483        assert_eq!(0, g.node(h2).in_degree());
1484        assert_eq!(0, g.node(h1).out_degree());
1485        assert_eq!(1, g.node(h2).out_degree());
1486        assert_eq!(1, g.node(o1).in_degree());
1487        assert_eq!(0, g.node(o1).out_degree());
1488        assert_eq!(1, g.link_count());
1489
1490        g.remove_all_inout_links_of_node(o1);
1491
1492        assert_eq!(0, g.node(i1).out_degree());
1493        assert_eq!(0, g.node(h1).in_degree());
1494        assert_eq!(0, g.node(h2).in_degree());
1495        assert_eq!(0, g.node(h1).out_degree());
1496        assert_eq!(0, g.node(h2).out_degree());
1497        assert_eq!(0, g.node(o1).in_degree());
1498        assert_eq!(0, g.node(o1).out_degree());
1499        assert_eq!(0, g.link_count());
1500    }
1501
1502    #[test]
1503    fn test_remove_node() {
1504        let mut g = Network::new();
1505        let i1 = g.add_node(NodeT::Input, ());
1506        let h1 = g.add_node(NodeT::Hidden, ());
1507        let h2 = g.add_node(NodeT::Hidden, ());
1508        let o1 = g.add_node(NodeT::Output, ());
1509
1510        g.add_link_unordered(i1, h1, 0.0, ());
1511        g.add_link_unordered(i1, h2, 0.0, ());
1512        g.add_link_unordered(h1, o1, 0.0, ());
1513        g.add_link_unordered(h2, o1, 0.0, ());
1514
1515        assert_eq!(2, g.node(i1).out_degree());
1516        assert_eq!(1, g.node(h1).in_degree());
1517        assert_eq!(1, g.node(h2).in_degree());
1518        assert_eq!(1, g.node(h1).out_degree());
1519        assert_eq!(1, g.node(h2).out_degree());
1520        assert_eq!(2, g.node(o1).in_degree());
1521        assert_eq!(0, g.node(o1).out_degree());
1522        assert_eq!(4, g.link_count());
1523        assert_eq!(4, g.node_count());
1524
1525        assert_eq!(NodeIndex(0), i1);
1526        assert_eq!(NodeIndex(3), o1);
1527        g.remove_node(i1);
1528        let o1 = i1;
1529        drop(i1);
1530        assert_eq!(NodeIndex(0), o1);
1531
1532        assert_eq!(0, g.node(h1).in_degree());
1533        assert_eq!(0, g.node(h2).in_degree());
1534        assert_eq!(1, g.node(h1).out_degree());
1535        assert_eq!(1, g.node(h2).out_degree());
1536        assert_eq!(2, g.node(o1).in_degree());
1537        assert_eq!(0, g.node(o1).out_degree());
1538        assert_eq!(2, g.link_count());
1539        assert_eq!(3, g.node_count());
1540
1541        assert_eq!(NodeIndex(2), h2);
1542        g.remove_node(h2);
1543        drop(h2);
1544
1545        assert_eq!(0, g.node(h1).in_degree());
1546        assert_eq!(1, g.node(h1).out_degree());
1547        assert_eq!(1, g.node(o1).in_degree());
1548        assert_eq!(0, g.node(o1).out_degree());
1549        assert_eq!(1, g.link_count());
1550        assert_eq!(2, g.node_count());
1551
1552        assert_eq!(NodeIndex(0), o1);
1553        g.remove_node(o1);
1554        let h1 = o1;
1555        drop(o1);
1556        assert_eq!(NodeIndex(0), h1);
1557
1558        assert_eq!(0, g.node(h1).in_degree());
1559        assert_eq!(0, g.node(h1).out_degree());
1560        assert_eq!(0, g.link_count());
1561        assert_eq!(1, g.node_count());
1562
1563        assert_eq!(NodeIndex(0), h1);
1564        g.remove_node(h1);
1565        assert_eq!(0, g.node_count());
1566    }
1567
1568}