<commit_before>#![feature(augmented_assignments)]
#![feature(op_assign_traits)]

use std::fmt::Debug;
use std::collections::BTreeMap;
use std::ops::AddAssign;
use std::ops::Neg;

#[derive(Debug, Clone)]
struct Edge<W: Debug + Clone> {
    src: usize,
    dst: usize,
    weight: W,
}

impl<W:Debug+Clone+Default> Edge<W> {
    fn new(src: usize, dst: usize) -> Edge<W> {
        Edge {
            src: src,
            dst: dst,
            weight: W::default(),
        }
    }
}

#[derive(Debug, Clone)]
struct Node<N: Clone + Default + Debug> {
    in_edges: Vec<usize>,
    out_edges: Vec<usize>,
    node_fn: N,
}

impl<N:Default+Clone+Debug> Node<N> {
    fn new() -> Node<N> {
        Node {
            in_edges: Vec::new(),
            out_edges: Vec::new(),
            node_fn: N::default(),
        }
    }
}

#[derive(Debug)]
pub struct GraphBuilder<W: Debug + Default + Clone, N: Debug + Default + Clone> {
    /// The current edge is always the edge on top of the stack.
    edges: BTreeMap<usize, Edge<W>>,
    nodes: Vec<Node<N>>,
    next_edge_id: usize,
    current_from_node: usize,
    current_to_node: usize,
    current_edge: usize,
}

#[derive(Debug)]
pub enum EdgeOperation<W, N> {
    IncreaseWeight {
        weight: W,
    },
    DecreaseWeight {
        weight: W,
    },
    Duplicate {
        weight: W,
    },
    Split {
        weight: W,
    },
    Loop {
        weight: W,
    },
    Output {
        weight: W,
    },
    Merge {
        n: u32,
    },
    Next {
        n: u32,
    },
    Parent {
        n: u32,
    },
    SetNodeFunction {
        function: N,
    },
    Reverse,
}


// We have to delete an edge if the (from, to) nodes would otherwise
// not much up with the edge in case of backtracking.

impl<W:Debug+Default+Clone+AddAssign<W>, N:Debug+Default+Clone> GraphBuilder<W, N> {
    pub fn new() -> GraphBuilder<W, N> {
        // we begin with an empty node and a virtual edge.

        GraphBuilder {
            edges: BTreeMap::new(),
            nodes: vec![Node::new()],
            next_edge_id: 1,
            current_from_node: 0,
            current_to_node: 0,
            current_edge: 0, /* this points to a non-existing edge by purpose! */
        }
    }
<commit_msg>Make EdgeOperation cloneable<commit_after>#![feature(augmented_assignments)]
#![feature(op_assign_traits)]

use std::fmt::Debug;
use std::collections::BTreeMap;
use std::ops::AddAssign;
use std::ops::Neg;

#[derive(Debug, Clone)]
struct Edge<W: Debug + Clone> {
    src: usize,
    dst: usize,
    weight: W,
}

impl<W:Debug+Clone+Default> Edge<W> {
    fn new(src: usize, dst: usize) -> Edge<W> {
        Edge {
            src: src,
            dst: dst,
            weight: W::default(),
        }
    }
}

#[derive(Debug, Clone)]
struct Node<N: Clone + Default + Debug> {
    in_edges: Vec<usize>,
    out_edges: Vec<usize>,
    node_fn: N,
}

impl<N:Default+Clone+Debug> Node<N> {
    fn new() -> Node<N> {
        Node {
            in_edges: Vec::new(),
            out_edges: Vec::new(),
            node_fn: N::default(),
        }
    }
}

#[derive(Debug)]
pub struct GraphBuilder<W: Debug + Default + Clone, N: Debug + Default + Clone> {
    /// The current edge is always the edge on top of the stack.
    edges: BTreeMap<usize, Edge<W>>,
    nodes: Vec<Node<N>>,
    next_edge_id: usize,
    current_from_node: usize,
    current_to_node: usize,
    current_edge: usize,
}

#[derive(Debug, Clone)]
pub enum EdgeOperation<W:Clone, N:Clone> {
    IncreaseWeight {
        weight: W,
    },
    DecreaseWeight {
        weight: W,
    },
    Duplicate {
        weight: W,
    },
    Split {
        weight: W,
    },
    Loop {
        weight: W,
    },
    Output {
        weight: W,
    },
    Merge {
        n: u32,
    },
    Next {
        n: u32,
    },
    Parent {
        n: u32,
    },
    SetNodeFunction {
        function: N,
    },
    Reverse,
}


// We have to delete an edge if the (from, to) nodes would otherwise
// not much up with the edge in case of backtracking.

impl<W:Debug+Default+Clone+AddAssign<W>, N:Debug+Default+Clone> GraphBuilder<W, N> {
    pub fn new() -> GraphBuilder<W, N> {
        // we begin with an empty node and a virtual edge.

        GraphBuilder {
            edges: BTreeMap::new(),
            nodes: vec![Node::new()],
            next_edge_id: 1,
            current_from_node: 0,
            current_to_node: 0,
            current_edge: 0, /* this points to a non-existing edge by purpose! */
        }
    }

    // XXX: Node function
{'fraction_non_alphanumeric': 0.13952464788732394, 'fraction_numerical': 0.0044014084507042256, 'mean_word_length': 2.096049046321526, 'pattern_counts': {'":': 0, '<': 43, '<?xml version=': 0, '>': 49, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2034161', 'n_tokens_mistral': 1573, 'n_tokens_neox': 1583, 'n_words': 400}