use std::{cmp,env,mem,ops,iter,marker,collections,hash};
use hadean::{Sender,Receiver,Connection,Process,ChannelType,Channel,pid,spawn,ProcessSendable};
use linked_hash_map;
pub struct Graph<V,E> where V: ProcessSendable, E: ProcessSendable {
graph: Vec<(V,Vec<(E,usize)>)>,
edges: usize
}
impl<V,E> Graph<V,E> where V: ProcessSendable, E: ProcessSendable {
pub fn new() -> Graph<V,E> {
Graph{graph:Vec::new(),edges:0}
}
pub fn add_vertex(&mut self, v: V) {
self.graph.push((v,Vec::new()));
}
pub fn add_edge(&mut self, a: usize, b: usize, e: E) {
assert!(b < self.graph.len());
self.graph[a].1.push((e,b));
self.edges += 1;
}
pub fn num_vertices(&self) -> usize {
self.graph.len()
}
pub fn num_edges(&self) -> usize {
self.edges
}
pub fn map<VM,EM,V1,E1>(self, vertex_map: VM, edge_map: EM) -> Graph<V1,E1> where VM: Fn(V) -> V1 + ProcessSendable, EM: Fn(E) -> E1 + ProcessSendable, V1: ProcessSendable, E1: ProcessSendable {
Graph{graph:self.graph.into_iter().map(|(vertex0,vertex1)| {
(
vertex_map(vertex0),
vertex1.into_iter().map(|(edge0,edge1)| {
(
edge_map(edge0),
edge1
)
}).collect()
)
}).collect(),edges:self.edges}
}
pub fn step<F1,F2,M>(&mut self, send: F1, receive: F2) where F1: Fn(V, EdgeIter<E,M>) + ProcessSendable, F2: Fn(V, MessageIter<M>) -> V + ProcessSendable, M: ProcessSendable {
}
pub fn step_reduce<F1,F2,F3,M>(&mut self, send: F1, initial: M, reduce: F2, receive: F3) where F1: Fn(V, EdgeIter<E,M>) + ProcessSendable, F2: Fn(M, M) -> M + ProcessSendable, F3: Fn(V, M) -> V + ProcessSendable, M: ProcessSendable {
}
}
pub struct Edge<E,M> where E: ProcessSendable, M: ProcessSendable {
attr: E,
offset: usize,
phantom: marker::PhantomData<M>
}
impl<E,M> Edge<E,M> where E: ProcessSendable, M: ProcessSendable {
pub fn send(&mut self, message: M) {
}
}
pub struct EdgeIter<'a,E,M> where E: 'a + ProcessSendable, M: ProcessSendable {
a: &'a[E],
phantom: marker::PhantomData<M>
}
impl<'a,E,M> EdgeIter<'a,E,M> where E: 'a + ProcessSendable, M: ProcessSendable {
pub fn len(&self) -> usize {
self.a.len()
}
}
impl<'a,E,M> iter::Iterator for EdgeIter<'a,E,M> where E: 'a + ProcessSendable, M: ProcessSendable {
type Item = Edge<E,M>;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
pub struct MessageIter<'a,E> where E: 'a + ProcessSendable {
a: &'a[E]
}
impl<'a,E> iter::Iterator for MessageIter<'a,E> where E: ProcessSendable {
type Item = E;
fn next(&mut self) -> Option<Self::Item> {
None
}
}
pub struct GraphConstructor<T,F,V,E> where T: cmp::Eq + hash::Hash + ProcessSendable, F: Fn(&T) -> V + ProcessSendable, V: ProcessSendable, E: ProcessSendable {
v: F,
map: linked_hash_map::LinkedHashMap<T,usize>,
links: Vec<Vec<(E,usize)>>
}
impl<T,F,V,E> GraphConstructor<T,F,V,E> where T: cmp::Eq + hash::Hash + ProcessSendable, F: Fn(&T) -> V + ProcessSendable, V: ProcessSendable, E: ProcessSendable {
pub fn new(v: F) -> GraphConstructor<T,F,V,E> {
GraphConstructor{v:v, map:linked_hash_map::LinkedHashMap::new(), links:Vec::new()}
}
pub fn push(&mut self, a: T, b: T, e: E) {
let count = self.map.len();
let a = if self.map.contains_key(&a) {
*self.map.get(&a).unwrap()
} else {
self.map.insert(a, count);
self.links.push(Vec::new());
count
};
let count = self.map.len();
let b = if self.map.contains_key(&b) {
*self.map.get(&b).unwrap()
} else {
self.map.insert(b, count);
self.links.push(Vec::new());
count
};
self.links[a].push((e,b));
}
pub fn construct(self) -> (Graph<V,E>,GraphInterpreter<T>) {
let mut graph = Graph::new();
let mut keys = Vec::new();
for (key,_) in self.map {
graph.add_vertex((self.v)(&key));
keys.push(key);
}
for (i,vertex_links) in self.links.into_iter().enumerate() {
for (e,link) in vertex_links {
graph.add_edge(i, link, e);
}
}
(graph, GraphInterpreter(keys))
}
}
pub struct GraphInterpreter<T>(Vec<T>) where T: cmp::Eq + hash::Hash + ProcessSendable;
impl<T> GraphInterpreter<T> where T: cmp::Eq + hash::Hash + ProcessSendable {
pub fn interpret<V,E>(self, graph: Graph<V,E>) -> collections::HashMap<T,V> where V: ProcessSendable, E: ProcessSendable {
let mut ret: collections::HashMap<T,V> = collections::HashMap::new();
assert!(self.0.len() == graph.graph.len());
for (key,v) in self.0.into_iter().zip(graph.graph.into_iter()) {
ret.insert(key, v.0);
}
ret
}
}