From ec81475745d1c8833b542855354b7a5b190fc9fb Mon Sep 17 00:00:00 2001 From: Linus Behrbohm Date: Sun, 17 Nov 2024 03:16:34 +0100 Subject: [PATCH] Use ChildDedupPass --- .vscode/launch.json | 8 +- Cargo.toml | 16 +- justlog | 2 +- ngrams/Cargo.toml | 16 +- ngrams/src/graph/labelling/frequency.rs | 29 ++-- ngrams/src/graph/labelling/wrapper.rs | 10 +- ngrams/src/graph/partitions/collect.rs | 195 ++++++++++++++++++++++++ ngrams/src/graph/partitions/mod.rs | 46 +++--- ngrams/src/graph/traversal/pass.rs | 2 +- ngrams/src/graph/traversal/queue.rs | 2 +- ngrams/src/graph/traversal/visited.rs | 6 +- ngrams/src/graph/utils/cover/child.rs | 2 +- ngrams/src/graph/utils/cover/parent.rs | 3 +- ngrams/src/graph/utils/dedup/mod.rs | 100 +++++++----- ngrams/src/graph/vocabulary/entry.rs | 4 +- ngrams/src/graph/vocabulary/mod.rs | 6 +- 16 files changed, 341 insertions(+), 106 deletions(-) create mode 100644 ngrams/src/graph/partitions/collect.rs diff --git a/.vscode/launch.json b/.vscode/launch.json index 40868dc..8197f57 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -13,14 +13,10 @@ "build", "--bin=graph_app", "--package=graph_app" - ], - "filter": { - "name": "graph_app", - "kind": "bin" - } + ] }, "args": [], - "cwd": "${workspaceFolder}" + "cwd": "${workspaceFolder}/graph_app" } ] } \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 298b888..3294d7f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,13 +5,17 @@ exclude = [ "./egui", "./egui/crates/eframe", "./tracing-egui", - "./petgraph" -] -members = [ - "seqraph", - "ngrams", - "graph_app" + "./petgraph", + "./minimal_options", + "./graph_app", + "./ngrams", + "./justlog" ] +#members = [ +# "seqraph", +# "ngrams", +# "graph_app" +#] [profile.release] opt-level = 2 # fast and small wasm diff --git a/justlog b/justlog index 2a53735..9e761c7 160000 --- a/justlog +++ b/justlog @@ -1 +1 @@ -Subproject commit 2a537357ae6c17c40c4d4c43b0b4e65ec5d9ff9a +Subproject commit 9e761c7b0af602f6a5b646364ca7ecc0d8db96ca diff --git a/ngrams/Cargo.toml b/ngrams/Cargo.toml index 4a38935..6376b32 100644 --- a/ngrams/Cargo.toml +++ b/ngrams/Cargo.toml @@ -10,22 +10,24 @@ test-hashing = [] [dependencies] ngram = "0.1" -csv = "1" +csv = "1.3.1" maplit = "^1" tap = "^1" itertools = "^0.13" -plotters = "^0.3" -derive_more = "^0.99" -derive-new = "^0.6" -derive_builder = "^0.20" +derive-new = "^0.7.0" +derive_builder = "^0.20.2" range-ext = "0.3.0" -pretty_assertions = "1.4.0" +pretty_assertions = "1.4.1" serde = { version = "1.0.203", features = ["derive"] } ciborium = "0.2" -lazy_static = "1.4.0" +lazy_static = "1.5.0" derivative = "^2.2" +[dependencies.derive_more] +version = "^1.0.0" +features = ["full"] + [dependencies.seqraph] path = "../seqraph" diff --git a/ngrams/src/graph/labelling/frequency.rs b/ngrams/src/graph/labelling/frequency.rs index 5ec1f9f..6d1d493 100644 --- a/ngrams/src/graph/labelling/frequency.rs +++ b/ngrams/src/graph/labelling/frequency.rs @@ -59,7 +59,7 @@ impl TraversalPass for FrequencyCtx<'_> for node in start.iter() { queue.extend_layer( - self.on_node(&node).unwrap_or_default() + self.on_node(node).unwrap_or_default() ); } self.labels.extend(start.iter().map(HasVertexKey::vertex_key)); @@ -70,21 +70,18 @@ impl TraversalPass for FrequencyCtx<'_> node: &Self::Node, ) -> Option> { - if self.labels.contains(&node) - { - None - } - else - { - let entry = self.vocab.get_vertex(node).unwrap(); - let next = self.entry_next(&entry); - if self.entry_is_frequent(&entry) - { - let key = entry.data.vertex_key(); - self.labels.insert(key); - } - Some(next) - } + self.labels.contains(node) + .then_some(None) + .unwrap_or_else(|| { + let entry = self.vocab.get_vertex(node).unwrap(); + let next = self.entry_next(&entry); + if self.entry_is_frequent(&entry) + { + let key = entry.data.vertex_key(); + self.labels.insert(key); + } + Some(next) + }) } fn begin_run(&mut self) { println!("Frequency Pass"); diff --git a/ngrams/src/graph/labelling/wrapper.rs b/ngrams/src/graph/labelling/wrapper.rs index eae50a1..163ed1b 100644 --- a/ngrams/src/graph/labelling/wrapper.rs +++ b/ngrams/src/graph/labelling/wrapper.rs @@ -19,7 +19,7 @@ use crate::graph::{ TopDown, TraversalDirection, }, - pass::TraversalPass, queue::{LayeredQueue, Queue}, visited::Visited, + pass::TraversalPass, queue::{LayeredQueue, Queue}, visited::VisitTracking, }, utils::cover::ChildCover, vocabulary::{ entry::VertexCtx, NGramId, @@ -44,18 +44,18 @@ pub struct WrapperCtx<'b> #[deref_mut] ctx: &'b mut LabellingCtx, #[new(default)] - visited: ::Collection, + visited_mut: ::Collection, } // - run bottom up (all smaller nodes need to be fully labelled) // - for each node x: // - run top down to find the largest frequent children to cover whole range // - label node x if there are multiple overlapping labelled child nodes -impl Visited for WrapperCtx<'_> +impl VisitTracking for WrapperCtx<'_> { type Collection = HashSet<::Node>; - fn visited<'t>(&'t mut self) -> &'t mut ::Collection { - &mut self.visited + fn visited_mut(&mut self) -> &mut ::Collection { + &mut self.visited_mut } } impl TraversalPass for WrapperCtx<'_> diff --git a/ngrams/src/graph/partitions/collect.rs b/ngrams/src/graph/partitions/collect.rs new file mode 100644 index 0000000..90037f0 --- /dev/null +++ b/ngrams/src/graph/partitions/collect.rs @@ -0,0 +1,195 @@ + +use derive_more::{ + Deref, + DerefMut, + IntoIterator, +}; +use derive_new::new; +use itertools::Itertools; +use std::collections::VecDeque; + +use crate::graph::{ + labelling::LabellingCtx, + partitions::container::PartitionContainer, + traversal::{ + direction::{ + TopDown, + TraversalDirection, + }, + pass::TraversalPass, queue::Queue, + }, + utils::cover::ChildCover, + vocabulary::{ + entry::{ + HasVertexEntries, + VertexCtx, + }, + NGramId, + ProcessStatus, + }, +}; +use seqraph::{ + graph::{ + getters::vertex::VertexSet, + vertex::{ + child::Child, + data::{ + VertexData, + VertexDataBuilder, + }, + has_vertex_index::{ + HasVertexIndex, + ToChild, + }, + has_vertex_key::HasVertexKey, + key::VertexKey, + pattern::id::PatternId, + wide::Wide, + VertexIndex, + }, + Hypergraph, + }, + HashMap, + HashSet, +}; + +use crate::graph::{traversal::{queue::{LayeredQueue, LinearQueue}, visited::VisitTracking}, vocabulary::Vocabulary}; + + +#[derive(Debug, Deref, DerefMut)] +pub struct AccumulateCtx<'b> +{ + #[deref] + #[deref_mut] + pub ctx: &'b mut LabellingCtx, + pub result: Hypergraph, + visited: ::Collection, +} + +impl<'b> From<&'b mut LabellingCtx> for AccumulateCtx<'b> { + fn from(ctx: &'b mut LabellingCtx) -> Self + { + Self { + ctx, + result: Default::default(), + visited: Default::default(), + } + } +} +impl VisitTracking for AccumulateCtx<'_> +{ + type Collection = HashSet<::Node>; + fn visited_mut(&mut self) -> &mut ::Collection { + &mut self.visited + } +} +impl TraversalPass for AccumulateCtx<'_> +{ + type Node = NGramId; + type NextNode = NGramId; + type Queue = LinearQueue; + fn start_queue(&mut self) -> Self::Queue { + let queue = Self::Queue::from_iter( + TopDown::starting_nodes(&self.vocab) + ); + for vk in queue.iter() + { + let data = self.vocab.containment.expect_vertex(vk.vertex_key()); + let mut builder = VertexDataBuilder::default(); + builder.width(data.width()); + builder.key(**vk); + self.result.insert_vertex_builder(builder); + } + queue + } + fn node_condition(&mut self, node: Self::Node) -> bool { + (!self.visited_mut().contains(&node) + && self.labels.contains(&node)) + || self.vocab.leaves.contains(&node) + .then(|| self.visited_mut().insert(node)) + .is_some() + } + fn on_node( + &mut self, + node: &NGramId, + ) -> Option> + { + //let container = PartitionContainer::from_ngram(self, *node); + //let entry = self.vocab.get_vertex(node).unwrap(); + + //let pids: Vec<_> = std::iter::repeat_n((), container.len()) + // .map(|_| PatternId::default()) + // .collect(); + + //let parent_data = self.result.expect_vertex_mut(node.vertex_key()); + + //// child patterns with indices in containment + //parent_data.children = pids.into_iter().zip(container).collect(); + + //// child locations parent in self.graph, children indices in self.vocab.containment + //let child_locations = parent_data + // .all_localized_children_iter() + // .into_iter() + // .map(|(l, c)| (l, *c)) + // .collect_vec(); + + // create child nodes in self.graph + // set child parents and translate child indices to self.graph + //for (loc, vi) in child_locations.iter().copied() + //{ + // let key = self.vocab.containment.expect_key_for_index(vi); + // let out_index = if let Ok(v) = self.result.get_vertex_mut(key) + // { + // v.add_parent(loc); + // v.vertex_index() + // } + // else + // { + // let mut builder = VertexDataBuilder::default(); + // builder.width(vi.width()); + // builder.key(key); + // let mut data = self.result.finish_vertex_builder(builder); + // data.add_parent(loc); + + // // translate containment index to output index + // let out = if vi.width() > 1 { + // self.result.insert_vertex_data(data) + // } else { + // self.result.insert_token_data(*self.vocab.containment.expect_token_by_key(&key), data) + // }.vertex_index(); + + // if !self.ctx.labels.contains(&key) { + // self.ctx.labels.insert(key); + // // TODO: Rerun frequency pass for subgraph of key + // } + // out + // }; + // self.result.expect_child_mut_at(loc).index = out_index; + //} + //let next = child_locations + // .clone() + // .into_iter() + // .flat_map(|(_, p)| p) + // .filter(|c| c.width() > 1) + // .map(|c| + // NGramId::new( + // self.vocab.get_vertex(&c).unwrap().data.vertex_key(), + // c.width(), + // ) + // ) + // .collect(); + let next = vec![]; + Some(next) + } + fn begin_run(&mut self) { + println!("Accumulate Pass"); + } + + fn finish_run(&mut self) { + self.vocab.roots.iter().for_each(|key| { + let _ = self.result.vertex_key_string(key); + }); + self.status = ProcessStatus::Partitions; + println!("{:#?}", &self.result); + } +} diff --git a/ngrams/src/graph/partitions/mod.rs b/ngrams/src/graph/partitions/mod.rs index 48811e8..328946b 100644 --- a/ngrams/src/graph/partitions/mod.rs +++ b/ngrams/src/graph/partitions/mod.rs @@ -1,4 +1,5 @@ pub mod container; +pub mod collect; use derive_more::{ Deref, @@ -54,7 +55,7 @@ use seqraph::{ HashSet, }; -use super::{traversal::{queue::LayeredQueue, visited::Visited}, vocabulary::Vocabulary}; +use super::{traversal::{queue::{LayeredQueue, LinearQueue}, visited::VisitTracking}, vocabulary::Vocabulary, utils::dedup::ChildDedupPass}; // - run top down (smaller nodes to label need to be found) // - for each node x: @@ -77,8 +78,8 @@ pub struct PartitionsCtx<'b> #[deref] #[deref_mut] pub ctx: &'b mut LabellingCtx, + visited: ::Collection, pub graph: Hypergraph, - visited: ::Collection, } impl<'b> From<&'b mut LabellingCtx> for PartitionsCtx<'b> { @@ -86,15 +87,15 @@ impl<'b> From<&'b mut LabellingCtx> for PartitionsCtx<'b> { { Self { ctx, - graph: Default::default(), visited: Default::default(), + graph: Default::default(), } } } -impl Visited for PartitionsCtx<'_> +impl VisitTracking for PartitionsCtx<'_> { type Collection = HashSet<::Node>; - fn visited<'t>(&'t mut self) -> &'t mut ::Collection { + fn visited_mut(&mut self) -> &mut ::Collection { &mut self.visited } } @@ -102,7 +103,7 @@ impl TraversalPass for PartitionsCtx<'_> { type Node = NGramId; type NextNode = NGramId; - type Queue = LayeredQueue; + type Queue = LinearQueue; fn start_queue(&mut self) -> Self::Queue { let queue = Self::Queue::from_iter( TopDown::starting_nodes(&self.vocab) @@ -117,6 +118,13 @@ impl TraversalPass for PartitionsCtx<'_> } queue } + fn node_condition(&mut self, node: Self::Node) -> bool { + (!self.visited_mut().contains(&node) + && self.labels.contains(&node)) + || self.vocab.leaves.contains(&node) + .then(|| self.visited_mut().insert(node)) + .is_some() + } fn on_node( &mut self, node: &NGramId, @@ -124,6 +132,9 @@ impl TraversalPass for PartitionsCtx<'_> { let container = PartitionContainer::from_ngram(self, *node); let entry = self.vocab.get_vertex(node).unwrap(); + if entry.ngram == "ab" || entry.ngram == "ba" { + println!("{}: {:?}", entry.ngram, self.ctx.labels); + } let pids: Vec<_> = std::iter::repeat_n((), container.len()) .map(|_| PatternId::default()) @@ -141,6 +152,14 @@ impl TraversalPass for PartitionsCtx<'_> .map(|(l, c)| (l, *c)) .collect_vec(); + let unlabelled = child_locations + .iter() + .map(|(_, vi)| self.vocab.containment.expect_key_for_index(*vi)) + .filter(|k| !self.labels.contains(k)) + .collect_vec(); + + ChildDedupPass::new(self.ctx, unlabelled).run(); + // create child nodes in self.graph // set child parents and translate child indices to self.graph for (loc, vi) in child_locations.iter().copied() @@ -166,10 +185,6 @@ impl TraversalPass for PartitionsCtx<'_> self.graph.insert_token_data(*self.vocab.containment.expect_token_by_key(&key), data) }.vertex_index(); - if !self.ctx.labels.contains(&key) { - self.ctx.labels.insert(key); - // TODO: Rerun frequency pass for subgraph of key - } out }; self.graph.expect_child_mut_at(loc).index = out_index; @@ -186,23 +201,18 @@ impl TraversalPass for PartitionsCtx<'_> ) ) .collect(); + //let next = vec![]; Some(next) } fn begin_run(&mut self) { println!("Partition Pass"); } - fn node_condition(&mut self, node: Self::Node) -> bool { - (!self.visited().contains(&node) - && self.labels.contains(&node)) - || self.vocab.leaves.contains(&node) - .then(|| self.visited().insert(node)) - .is_some() - } + fn finish_run(&mut self) { self.vocab.roots.iter().for_each(|key| { let _ = self.graph.vertex_key_string(key); }); - self.status = ProcessStatus::Partitions; println!("{:#?}", &self.graph); + self.status = ProcessStatus::Partitions; } } diff --git a/ngrams/src/graph/traversal/pass.rs b/ngrams/src/graph/traversal/pass.rs index f4e1780..75343d0 100644 --- a/ngrams/src/graph/traversal/pass.rs +++ b/ngrams/src/graph/traversal/pass.rs @@ -18,7 +18,7 @@ use seqraph::graph::vertex::{ VertexIndex, }; -use super::{queue::Queue, visited::{Visited, VisitorCollection}}; +use super::{queue::Queue, visited::{VisitTracking, VisitorCollection}}; pub trait PassNode: Eq + PartialEq + Debug + Clone + Hash {} impl PassNode for N {} diff --git a/ngrams/src/graph/traversal/queue.rs b/ngrams/src/graph/traversal/queue.rs index e72a888..72ea2e7 100644 --- a/ngrams/src/graph/traversal/queue.rs +++ b/ngrams/src/graph/traversal/queue.rs @@ -1,4 +1,4 @@ -use std::{collections::VecDeque, ops::{Deref, DerefMut}}; +use std::{collections::VecDeque}; use itertools::Itertools; diff --git a/ngrams/src/graph/traversal/visited.rs b/ngrams/src/graph/traversal/visited.rs index 97c3056..308c222 100644 --- a/ngrams/src/graph/traversal/visited.rs +++ b/ngrams/src/graph/traversal/visited.rs @@ -22,9 +22,9 @@ use seqraph::{ use super::pass::PassNode; -pub trait Visited: TraversalPass { +pub trait VisitTracking: TraversalPass { type Collection: VisitorCollection; - fn visited(&mut self) -> &mut Self::Collection; + fn visited_mut(&mut self) -> &mut Self::Collection; } pub trait VisitorCollection { type Ref<'t>: VisitorCollection where N: 't; @@ -38,7 +38,7 @@ impl VisitorCollection for HashSet <&mut Self as VisitorCollection>::insert(&mut &mut *self, node) } } -impl<'a, N: PassNode> VisitorCollection for &'a mut HashSet { +impl VisitorCollection for &'_ mut HashSet { type Ref<'t> = &'t mut HashSet where N: 't; fn insert(&mut self, node: N) -> bool { HashSet::insert(*self, node) diff --git a/ngrams/src/graph/utils/cover/child.rs b/ngrams/src/graph/utils/cover/child.rs index b9e18ef..7976d00 100644 --- a/ngrams/src/graph/utils/cover/child.rs +++ b/ngrams/src/graph/utils/cover/child.rs @@ -50,7 +50,7 @@ use crate::graph::{ TopDown, TraversalDirection, }, - pass::TraversalPass, queue::{LayeredQueue, Queue}, visited::Visited, + pass::TraversalPass, queue::{LayeredQueue, Queue}, visited::VisitTracking, }, vocabulary::{ entry::{ diff --git a/ngrams/src/graph/utils/cover/parent.rs b/ngrams/src/graph/utils/cover/parent.rs index cbc7ade..fdf29c2 100644 --- a/ngrams/src/graph/utils/cover/parent.rs +++ b/ngrams/src/graph/utils/cover/parent.rs @@ -50,7 +50,7 @@ use crate::graph::{ TopDown, TraversalDirection, }, - pass::TraversalPass, queue::{LayeredQueue, Queue}, visited::Visited, + pass::TraversalPass, queue::{LayeredQueue, Queue}, visited::VisitTracking, }, vocabulary::{ entry::{ @@ -121,7 +121,6 @@ impl TraversalPass for ParentCoverPass<'_> { { while let Some(node) = queue.pop_front() { - let node = node.into(); if let Some(next) = self.node_condition(node) .then(|| self.on_node(&node)) .flatten() diff --git a/ngrams/src/graph/utils/dedup/mod.rs b/ngrams/src/graph/utils/dedup/mod.rs index 3bfe682..111b76c 100644 --- a/ngrams/src/graph/utils/dedup/mod.rs +++ b/ngrams/src/graph/utils/dedup/mod.rs @@ -22,14 +22,10 @@ use std::{ cmp::{ Ordering, Reverse, - }, - collections::VecDeque, - fmt::{ + }, collections::VecDeque, fmt::{ Display, Formatter, - }, - num::NonZeroUsize, - ops::Range, + }, hash::Hash, num::NonZeroUsize, ops::Range }; use derive_new::new; @@ -50,7 +46,7 @@ use crate::graph::{ TopDown, TraversalDirection, }, - pass::TraversalPass, queue::{LayeredQueue, Queue}, visited::Visited, + pass::TraversalPass, queue::{LayeredQueue, LinearQueue, Queue}, visited::VisitTracking, }, vocabulary::{ entry::{ @@ -67,56 +63,92 @@ use super::cover::ChildCover; #[derive(Debug)] pub struct ChildDedupPass<'a> { - pub ctx: &'a LabellingCtx, + pub ctx: &'a mut LabellingCtx, pub covers: HashMap, + roots: Vec, + pub visited: HashSet, } impl<'a> ChildDedupPass<'a> { - pub fn new(ctx: &'a LabellingCtx, roots: impl IntoIterator) -> Self { + pub fn new(ctx: &'a mut LabellingCtx, roots: impl IntoIterator) -> Self { + let roots: Vec<_> = roots.into_iter().collect(); Self { ctx, - covers: roots.into_iter().map(|root| (root, ChildCover::default())).collect(), + covers: roots.iter().map(|root| (*root, ChildCover::default())).collect(), + roots, + visited: Default::default(), } } } - impl TraversalPass for ChildDedupPass<'_> { type Node = (VertexKey, usize, NGramId); type NextNode = (VertexKey, usize, NGramId); - type Queue = LayeredQueue; + type Queue = LinearQueue; fn start_queue(&mut self) -> Self::Queue { Self::Queue::from_iter( - //TopDown::next_nodes(&self.ctx.vocab.expect_vertex(&self.root)) - self.covers.iter().flat_map(|(key, tree)| - TopDown::next_nodes(&self.ctx.vocab.expect_vertex(key)) + //self.roots.iter() + // .map(|&root| (0, NGramId::new(root, self.ctx.vocab.expect_vertex(&root).width()))) + self.covers.iter().flat_map(|(root, tree)| { + self.ctx.labels.insert(*root); + TopDown::next_nodes(&self.ctx.vocab.expect_vertex(root)) .into_iter() - .map(|(p, n)| (*key, p, n)) - ) + .map(|(p, n)| (*root, p, n)) + }) ) } fn on_node(&mut self, node: &Self::Node) -> Option> { let &(root, off, node) = node; + let entry = self.ctx.vocab.get_vertex(&node).unwrap(); + if entry.ngram == "ab" || entry.ngram == "ba" { + let re = self.ctx.vocab.get_vertex(&root).unwrap(); + println!("{}({})found in root {}({})", entry.ngram, entry.vertex_key(), re.ngram, root); + } let cover = self.covers.get_mut(&root).unwrap(); // check if covered - if cover.any_covers(off, node) - { - None - } - else if self.ctx.labels.contains(&node) - { + let next = (node.vertex_key() == root).then(|| { cover.insert(off, node); - None - } - else - { + Some(()) + }) + .unwrap_or_else(|| + if cover.any_covers(off, &node) + { + None + } + else if self.visited.contains(&node) + { + self.ctx.labels.insert(node.vertex_key()); + cover.insert(off, node); + None + } + else if self.ctx.labels.contains(&node) + { + cover.insert(off, node); + None + } else { + Some(()) + } + ); + self.visited.insert(node.vertex_key()); + next.map(|_| { let ne = self.ctx.vocab.get_vertex(&node).unwrap(); - Some( - TopDown::next_nodes(&ne) - .into_iter() - .map(|(o, c)| (root, o + off, c)) - .collect() - ) - } + TopDown::next_nodes(&ne) + .into_iter() + .map(|(o, c)| (root, o + off, c)) + .collect() + }) } + //fn finish_run(&mut self) { + // self.roots.iter().for_each(|&root| { + // self.covers + // .get_mut(&root).unwrap() + // .insert( + // 0, + // NGramId::new( + // root, + // self.ctx.vocab.expect_vertex(&root).width(), + // ) + // ); + // }) + //} } \ No newline at end of file diff --git a/ngrams/src/graph/vocabulary/entry.rs b/ngrams/src/graph/vocabulary/entry.rs index 6503459..e6044df 100644 --- a/ngrams/src/graph/vocabulary/entry.rs +++ b/ngrams/src/graph/vocabulary/entry.rs @@ -104,14 +104,14 @@ pub trait HasVertexEntries key: &K, ) -> VertexCtx { self.get_vertex(key) - .expect(&format!("No VertexKey: {:?}", key)) + .unwrap_or_else(|| panic!("No VertexKey: {:?}", key)) } fn expect_vertex_mut( &mut self, key: &K, ) -> VertexCtxMut { self.get_vertex_mut(key) - .expect(&format!("No VertexKey: {:?}", key)) + .unwrap_or_else(|| panic!("No VertexKey: {:?}", key)) } } pub trait VocabIndex: HasVertexIndex {} diff --git a/ngrams/src/graph/vocabulary/mod.rs b/ngrams/src/graph/vocabulary/mod.rs index 79e2740..a8d48b2 100644 --- a/ngrams/src/graph/vocabulary/mod.rs +++ b/ngrams/src/graph/vocabulary/mod.rs @@ -73,10 +73,10 @@ pub struct NGramId pub key: VertexKey, pub width: usize, } -impl Into for NGramId +impl From for VertexKey { - fn into(self) -> VertexKey { - self.key + fn from(ngram_id: NGramId) -> Self { + ngram_id.key } } impl HasVertexKey for NGramId