1use graphs::adjset::{AdjSetEdge, UndirectedEdge};
38use prelude::*;
39use props::HashMapProp;
40
41use fera_fun::vec;
42use quickcheck::{Arbitrary, Gen};
43use rand::Rng;
44
45use std::cmp;
46use std::collections::HashSet;
47use std::fmt::Debug;
48
49fn shrink_graph<G>(g: &G) -> Box<Iterator<Item = G>>
50where
51 G: EdgeList + VertexList + WithBuilder,
52 G::Kind: UniformEdgeKind,
53{
54 let mut id: HashMapProp<Vertex<G>, usize> = g.vertex_prop(0);
55 for (i, v) in g.vertices().enumerate() {
56 id[v] = i;
57 }
58 let edges = vec(g.edges_ends().map(|(u, v)| (id[u], id[v])));
59 let iter = edges.shrink().map(|edges| {
60 let n = edges
61 .iter()
62 .map(|&(u, v)| cmp::max(u, v) + 1)
63 .max()
64 .unwrap_or(0);
65 if G::Kind::is_undirected() {
66 let set: HashSet<_> = edges
67 .iter()
68 .filter(|&&(u, v)| u != v)
69 .map(|&(u, v)| UndirectedEdge::new(u, v))
70 .collect();
71 let edges = set.into_iter().map(|e| (e.source(), e.target()));
72 G::new_with_edges(n, edges)
73 } else {
74 let set: HashSet<_> = edges.iter().filter(|&&(u, v)| u != v).cloned().collect();
75 G::new_with_edges(n, set)
76 }
77 });
78 Box::new(iter)
79}
80
81macro_rules! def_random {
82 ($(#[$name_meta:meta])* $name:ident,
83 $(#[$namev_meta:meta])* $namev:ident,
84 $(#[$namee_meta:meta])* $namee:ident,
85 $fun:ident) => (
86 $(#[$name_meta])*
87 #[derive(Clone, Debug)]
88 pub struct $name<G>(pub G);
89
90 impl<G> Arbitrary for $name<G>
91 where G: Clone + Send + 'static + VertexList + EdgeList + WithBuilder,
92 G::Kind: UniformEdgeKind
93 {
94 fn arbitrary<Ge: Gen>(gen: &mut Ge) -> Self {
95 let s = gen.size();
96 let n = gen.gen_range(0, s);
97 $name(G::$fun(n, gen))
98 }
99
100 fn shrink(&self) -> Box<Iterator<Item = Self>> {
101 Box::new(shrink_graph(&self.0).map($name))
102 }
103 }
104
105 $(#[$namev_meta])*
106 #[derive(Clone, Debug)]
107 pub struct $namev<G, T>(pub G, pub DefaultVertexPropMut<G, T>)
108 where G: WithVertexProp<T>,
109 DefaultVertexPropMut<G, T>: Debug + Clone;
110
111 impl<G, T> Arbitrary for $namev<G, T>
112 where G: Clone + Send + 'static + VertexList + EdgeList + WithBuilder,
113 G::Kind: UniformEdgeKind,
114 G: WithVertexProp<T>,
115 DefaultVertexPropMut<G, T>: Debug + Clone + Send + 'static,
116 T: Arbitrary + Default + Clone
117 {
118 fn arbitrary<Ge: Gen>(g: &mut Ge) -> Self {
119 let $name(graph) = $name::<G>::arbitrary(g);
120 let prop = graph.default_vertex_prop_from_fn(|_| T::arbitrary(g));
121 $namev(graph, prop)
122 }
123
124 fn shrink(&self) -> Box<Iterator<Item = Self>> {
125 let g = $name(self.0.clone());
126 let prop = self.1.clone();
127 let iter = g.shrink()
128 .map(move |g| {
129 let prop = g.0.default_vertex_prop_from_fn(|v| prop[v].clone());
130 $namev(g.0, prop)
131 });
132 Box::new(iter)
133 }
134 }
135
136 $(#[$namee_meta])*
137 #[derive(Clone, Debug)]
138 pub struct $namee<G, T>(pub G, pub DefaultEdgePropMut<G, T>)
139 where G: WithEdgeProp<T>,
140 DefaultEdgePropMut<G, T>: Debug + Clone;
141
142 impl<G, T> Arbitrary for $namee<G, T>
143 where G: Clone + Send + 'static + VertexList + EdgeList + WithBuilder,
144 G::Kind: UniformEdgeKind,
145 G: WithEdgeProp<T>,
146 DefaultEdgePropMut<G, T>: Debug + Clone + Send + 'static,
147 T: Arbitrary + Default + Clone
148 {
149 fn arbitrary<Ge: Gen>(g: &mut Ge) -> Self {
150 let $name(graph) = $name::<G>::arbitrary(g);
151 let prop = graph.default_edge_prop_from_fn(|_| T::arbitrary(g));
152 $namee(graph, prop)
153 }
154
155 fn shrink(&self) -> Box<Iterator<Item = Self>> {
156 let g = $name(self.0.clone());
157 let prop = self.1.clone();
158 let iter = g.shrink()
159 .map(move |$name(gn)| {
160 let mut propn = gn.default_edge_prop(T::default());
161 for (en, u, v) in gn.edges_with_ends() {
162 if let Some(e) = g.0.get_edge_by_ends(u, v) {
163 propn[en] = prop[e].clone();
164 }
165 }
166 $namee(gn, propn)
167 });
168 Box::new(iter)
169 }
170 }
171 )
172}
173
174def_random!{
175 Gn,
179
180 GnWithVertexProp,
184
185 GnWithEdgeProp,
189
190 new_gn
191}
192
193def_random!{
194 GnConnected,
198
199 GnConnectedWithVertexProp,
204
205 GnConnectedWithEdgeProp,
210 new_gn_connected
211}
212
213impl Arbitrary for CompleteGraph {
215 fn arbitrary<G: Gen>(gen: &mut G) -> Self {
216 let s = gen.size();
217 let n = gen.gen_range(0, s) as u32;
218 CompleteGraph::new(n)
219 }
220
221 fn shrink(&self) -> Box<Iterator<Item = Self>> {
222 let n = self.num_vertices();
223 Box::new(n.shrink().map(|n| CompleteGraph::new(n as u32)))
224 }
225}