diff --git a/ngrams/src/graph/partitions/container/builder.rs b/ngrams/src/graph/partitions/container/builder.rs index 2629abb..98a4289 100644 --- a/ngrams/src/graph/partitions/container/builder.rs +++ b/ngrams/src/graph/partitions/container/builder.rs @@ -11,11 +11,14 @@ use derive_more::{ }; use itertools::Itertools; use ngram::NGram; -use seqraph::graph::vertex::{ - child::Child, - has_vertex_index::HasVertexIndex, - has_vertex_key::HasVertexKey, - wide::Wide, +use seqraph::graph::{ + vertex::{ + child::Child, + has_vertex_index::HasVertexIndex, + has_vertex_key::HasVertexKey, + wide::Wide, + }, + getters::vertex::VertexSet, }; use std::{ cmp::{ @@ -67,8 +70,8 @@ impl<'a, 'b> PartitionLineBuilder<'a, 'b> offset: NonZeroUsize, ) { - let index = self.ctx.vocab.get_vertex_subrange( - &self.ctx.root.vertex_key(), + let index = self.ctx.vocab.containment.get_vertex_subrange( + self.ctx.root.vertex_key(), self.pos..(self.pos + offset.get()), ); self.push_cell(index); diff --git a/ngrams/src/graph/partitions/container/mod.rs b/ngrams/src/graph/partitions/container/mod.rs index 8b4d13f..29f7531 100644 --- a/ngrams/src/graph/partitions/container/mod.rs +++ b/ngrams/src/graph/partitions/container/mod.rs @@ -5,7 +5,7 @@ use crate::graph::{ NodePartitionCtx, PartitionsCtx, }, - vocabulary::NGramId, + vocabulary::{entry::VocabEntry, NGramId}, }; use builder::PartitionBuilder; use derive_more::{ @@ -32,6 +32,43 @@ use std::{ num::NonZeroUsize, }; +use derive_new::new; +use std::collections::VecDeque; + +use crate::graph::{ + labelling::LabellingCtx, + traversal::{ + TopDown, + TraversalPolicy, + }, + vocabulary::{ + entry::{ + HasVertexEntries, + VertexCtx, + }, + ProcessStatus, + }, +}; +use seqraph::{ + graph::{ + getters::vertex::VertexSet, + vertex::{ + data::{ + VertexData, + VertexDataBuilder, + }, + has_vertex_index::{ + HasVertexIndex, + ToChild, + }, + VertexIndex, + }, + Hypergraph, + }, + HashMap, + HashSet, +}; + #[derive(Debug, Copy, Clone)] pub enum PartitionCell { @@ -49,6 +86,65 @@ impl PartitionCell } } } +#[derive(Debug, Deref, DerefMut, Default, IntoIterator)] +pub struct ChildTree +{ + #[deref] + #[deref_mut] + #[into_iterator(owned, ref)] + entries: HashMap, +} + + +impl ChildTree +{ + // find largest labelled children + pub fn from_entry( + ctx: &PartitionsCtx<'_>, + entry: &VertexCtx<'_>, + ) -> Self + { + let mut queue: VecDeque<_> = + TopDown::next_nodes(entry).into_iter().collect(); + let mut tree: ChildTree = Default::default(); + + let mut visited: HashSet<_> = Default::default(); + while let Some((off, node)) = queue.pop_front() + { + if visited.contains(&(off, node)) + { + continue; + } + visited.insert((off, node)); + // check if covered + if tree.any_covers(off, node) + { + continue; + } + if ctx.labels.contains(&node) + { + tree.insert(off, node); + } + else + { + let ne = entry.vocab.get_vertex(&node).unwrap(); + queue.extend( + TopDown::next_nodes(&ne) + .into_iter() + .map(|(o, c)| (o + off, c)), + ) + } + } + tree + } + pub fn any_covers(&self, off: usize, node: impl Wide) -> bool { + self.iter().any(|(&p, &c)| { + let node_end = off + node.width(); + let probe_end = p + c.width(); + p <= off && node_end <= probe_end + }) + } +} #[derive(Debug, IntoIterator, Deref)] pub struct PartitionContainer @@ -57,6 +153,24 @@ pub struct PartitionContainer } impl PartitionContainer { + pub fn from_entry(ctx: &PartitionsCtx<'_>, entry: &VertexCtx) -> Self { + // find all largest children + let tree = ChildTree::from_entry(ctx, entry); + assert!( + match entry.width() { + 1 => tree.is_empty(), + _ => !tree.is_empty() + } + ); + + // build container with gaps + //let next = tree.iter().map(|(_, c)| c.vertex_index()).collect(); + let ctx = NodePartitionCtx::new( + NGramId::new(entry.data.vertex_key(), entry.data.width()), + ctx, + ); + Self::from_child_list(&ctx, tree) + } pub fn from_child_list( ctx: &NodePartitionCtx, list: impl IntoIterator, diff --git a/ngrams/src/graph/partitions/mod.rs b/ngrams/src/graph/partitions/mod.rs index c78092c..17ac8ef 100644 --- a/ngrams/src/graph/partitions/mod.rs +++ b/ngrams/src/graph/partitions/mod.rs @@ -3,6 +3,7 @@ mod container; use derive_more::{ Deref, DerefMut, + IntoIterator, }; use derive_new::new; use itertools::Itertools; @@ -10,7 +11,7 @@ use std::collections::VecDeque; use crate::graph::{ labelling::LabellingCtx, - partitions::container::PartitionContainer, + partitions::container::{ChildTree, PartitionContainer}, traversal::{ TopDown, TraversalPolicy, @@ -82,69 +83,18 @@ impl<'b> PartitionsCtx<'b> graph: Default::default(), } } - // find largest labelled children - fn child_tree( - &self, - entry: &VertexCtx, - ) -> HashMap - { - let mut queue: VecDeque<_> = - TopDown::next_nodes(entry).into_iter().collect(); - let mut tree: HashMap = Default::default(); - let mut visited: HashSet<_> = Default::default(); - while let Some((off, node)) = queue.pop_front() - { - if visited.contains(&(off, node)) - { - continue; - } - visited.insert((off, node)); - // check if covered - if tree.iter().any(|(&p, &c)| { - let node_end = off + node.width(); - let probe_end = p + c.width(); - p <= off && node_end <= probe_end - }) - { - continue; - } - if self.labels.contains(&node) - { - tree.insert(off, node); - } - else - { - let ne = entry.vocab.get_vertex(&node).unwrap(); - queue.extend( - TopDown::next_nodes(&ne) - .into_iter() - .map(|(o, c)| (o + off, c)), - ) - } - } - tree - } fn on_node( &mut self, node: &NGramId, ) -> Vec { + if node.width() == 1 { + return Vec::new(); + } let entry = self.vocab.get_vertex(node).unwrap(); - - // find all largest children - let tree = self.child_tree(&entry); - - // build container with gaps - //let next = tree.iter().map(|(_, c)| c.vertex_index()).collect(); - let ctx = NodePartitionCtx::new( - NGramId::new(entry.data.vertex_key(), entry.data.width()), - self, - ); - let container = PartitionContainer::from_child_list(&ctx, tree); - //println!("{:#?}", container); - //print!("{}", container); - + let container = PartitionContainer::from_entry(self, &entry); + let pids: Vec<_> = std::iter::repeat_n((), container.len()) .map(|_| PatternId::default()) .collect(); @@ -156,9 +106,17 @@ impl<'b> PartitionsCtx<'b> ); let parent_data = self.graph.get_vertex_mut(node.vertex_key()).expect(&err); + assert!( + match parent_data.width() { + 0 => panic!("Invalid width of zero."), + 2 => pids.len() == 1, + 1 => pids.is_empty(), + _ => !pids.is_empty(), + } + ); // child patterns with indices in containment - parent_data.children = pids.into_iter().zip(container.clone()).collect(); + 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() @@ -172,17 +130,18 @@ impl<'b> PartitionsCtx<'b> .map(|(_, c)| c.vertex_index()) .sorted() .collect_vec(), - container + parent_data.children .iter() - .flatten() - .map(HasVertexIndex::vertex_index) + .flat_map(|(_, p)| p) + .map(|c| c.vertex_index()) .sorted() .collect_vec(), ); + // create child nodes in self.graph // set child parents and translate child indices to self.graph - for (loc, vi) in child_locations.into_iter() + 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.graph.get_vertex_mut(key) @@ -198,6 +157,7 @@ impl<'b> PartitionsCtx<'b> let mut data = self.graph.finish_vertex_builder(builder); assert!(data.key == key); data.add_parent(loc); + // translate containment index to output index if vi.width() > 1 { self.graph.insert_vertex_data(data) @@ -207,17 +167,19 @@ impl<'b> PartitionsCtx<'b> }; self.graph.expect_child_mut_at(loc).index = out_index; } - container + let parent_data = self.graph.get_vertex_mut(node.vertex_key()).expect(&err); + child_locations + .clone() .into_iter() - .flatten() + .flat_map(|(_, p)| p) .filter(|c| c.width() > 1) .map(|c| { let entry = self.vocab.get_vertex(&c).unwrap(); let key = entry.data.vertex_key(); - assert!( - self.graph.contains_vertex(key), - "{:#?}", entry.entry, - ); + //assert!( + // self.graph.contains_vertex(key), + // "{:#?}", entry.entry, + //); NGramId::new( key, c.width(), @@ -229,26 +191,24 @@ impl<'b> PartitionsCtx<'b> { println!("Partition Pass"); let mut queue: VecDeque<_> = TopDown::starting_nodes(&self.vocab); - //let mut n = 0; for vk in queue.iter() { - let entry = self.vocab.get_vertex(vk).unwrap(); + let data = self.vocab.containment.expect_vertex(vk.vertex_key()); let mut builder = VertexDataBuilder::default(); - builder.width(entry.data.width()); + builder.width(data.width()); builder.key(**vk); self.graph.insert_vertex_builder(builder); } + while !queue.is_empty() { - //println!("{}", n); - //n += 1; let mut visited: HashSet<_> = Default::default(); let mut next_layer: Vec<_> = Default::default(); while let Some(node) = queue.pop_front() { if !visited.contains(&node) && self.labels.contains(&node) - && !self.vocab.leaves.contains(&node) + //&& !self.vocab.leaves.contains(&node) { next_layer.extend(self.on_node(&node)); visited.insert(node); @@ -256,6 +216,9 @@ impl<'b> PartitionsCtx<'b> } queue.extend(next_layer) } + self.vocab.roots.iter().for_each(|key| { + let _ = self.graph.vertex_key_string(key); + }); self.status = ProcessStatus::Partitions; println!("{:#?}", &self.graph); } diff --git a/ngrams/src/graph/traversal.rs b/ngrams/src/graph/traversal.rs index 62e7992..d7982ed 100644 --- a/ngrams/src/graph/traversal.rs +++ b/ngrams/src/graph/traversal.rs @@ -47,11 +47,11 @@ impl TraversalPolicy for BottomUp .data .parents .iter() - .filter(|(&id, p)| p.width == entry.entry.ngram.len() + 1) + .filter(|(&id, p)| p.width == entry.data.width() + 1) .map(|(id, p)| { NGramId::new( entry.vocab.containment.expect_key_for_index(id), - entry.data.width, + p.width(), ) }) .collect_vec() @@ -75,24 +75,19 @@ impl TraversalPolicy for TopDown { entry .data - .children - .iter() - .flat_map(|(_, pat)| { - pat.iter() - .enumerate() - .filter(|(subi, c)| c.width() + 1 == entry.entry.ngram.len()) - .map(|(subi, c)| { - ( - // sub index can be used as offset because child patterns have special structure - subi, - NGramId::new( - entry.vocab.containment.expect_key_for_index(c), - c.width(), - ), - ) - }) + .top_down_containment_nodes() + .into_iter() + .map(|(subi, c)| { + ( + // sub index can be used as offset because child patterns have special structure + subi, + NGramId::new( + entry.vocab.containment.expect_key_for_index(c), + c.width(), + ), + ) }) - .sorted_by_key(|&(off, _)| off) - .collect_vec() + .collect() + } } diff --git a/ngrams/src/graph/vocabulary/entry.rs b/ngrams/src/graph/vocabulary/entry.rs index 20f5bb2..eb8a809 100644 --- a/ngrams/src/graph/vocabulary/entry.rs +++ b/ngrams/src/graph/vocabulary/entry.rs @@ -1,4 +1,5 @@ use derive_more::Deref; +use seqraph::graph::vertex::wide::Wide; use serde::{ Deserialize, Serialize, @@ -62,6 +63,11 @@ pub struct VertexCtx<'a> pub entry: &'a VocabEntry, pub vocab: &'a Vocabulary, } +impl<'a> Wide for VertexCtx<'a> { + fn width(&self) -> usize { + self.data.width() + } +} impl<'a> VertexCtx<'a> { pub fn direct_parents(&self) -> &HashMap diff --git a/ngrams/src/graph/vocabulary/mod.rs b/ngrams/src/graph/vocabulary/mod.rs index df707ec..dce6eec 100644 --- a/ngrams/src/graph/vocabulary/mod.rs +++ b/ngrams/src/graph/vocabulary/mod.rs @@ -146,35 +146,6 @@ impl Vocabulary }.on_corpus(&mut vocab); vocab } - /// get sub-vertex at range relative to index - pub fn get_vertex_subrange( - &self, - index: &VertexKey, - range: Range, - ) -> Child - { - let mut entry = self.get_vertex(index).unwrap(); - let mut wrap = 0..entry.len(); - assert!(wrap.start <= range.start && wrap.end >= range.end); - - while range != wrap - { - let next = TopDown::next_nodes(&entry) - .into_iter() - .map( - |(pos, c)| (c.vertex_key(), pos..pos + c.width()), //pos <= range.start || pos + c.width() >= range.end - ) - .find_or_first(|(_, w)| { - w.start == range.start || w.end == range.end - }) - .unwrap(); - - entry = self.get_vertex(&next.0).unwrap(); - wrap = next.1; - } - - entry.data.to_child() - } //pub fn clean(&mut self) -> HashSet { // let drained: HashSet<_> = self.entries // .extract_if(|_, e| !e.needs_node()) diff --git a/seqraph/src/graph/getters/advanced.rs b/seqraph/src/graph/getters/advanced.rs index bef5002..c440515 100644 --- a/seqraph/src/graph/getters/advanced.rs +++ b/seqraph/src/graph/getters/advanced.rs @@ -1,13 +1,17 @@ +use std::ops::Range; use std::slice::SliceIndex; +use crate::graph::vertex::has_vertex_data::HasVertexData; +use crate::graph::vertex::wide::Wide; use crate::graph::Hypergraph; use crate::graph::kind::GraphKind; use crate::graph::vertex::child::Child; -use crate::graph::vertex::has_vertex_index::HasVertexIndex; +use crate::graph::vertex::has_vertex_index::{HasVertexIndex, ToChild}; use crate::graph::vertex::location::pattern::IntoPatternLocation; use crate::graph::vertex::parent::PatternIndex; use crate::graph::vertex::pattern::pattern_range::PatternRangeIndex; use crate::search::NoMatch; use crate::graph::getters::vertex::VertexSet; +use itertools::Itertools; impl Hypergraph { pub fn get_common_pattern_in_parent( @@ -62,4 +66,34 @@ impl Hypergraph { self.expect_vertex(loc.parent) .expect_child_pattern_range(&loc.id, range) } + /// get sub-vertex at range relative to index + pub fn get_vertex_subrange( + &self, + vertex: impl HasVertexData, + range: Range, + ) -> Child + { + + let mut data = vertex.vertex(&self); + let mut wrap = 0..data.width(); + assert!(wrap.start <= range.start && wrap.end >= range.end); + + while range != wrap + { + let next = data.top_down_containment_nodes() + .into_iter() + .map( + |(pos, c)| (c.vertex_index(), pos..pos + c.width()), //pos <= range.start || pos + c.width() >= range.end + ) + .find_or_first(|(_, w)| { + w.start == range.start || w.end == range.end + }) + .unwrap(); + + data = self.expect_vertex(next.0); + wrap = next.1; + } + + data.to_child() + } } diff --git a/seqraph/src/graph/getters/token.rs b/seqraph/src/graph/getters/token.rs index dacddca..4713761 100644 --- a/seqraph/src/graph/getters/token.rs +++ b/seqraph/src/graph/getters/token.rs @@ -1,46 +1,57 @@ -use crate::graph::getters::vertex::VertexSet; -use crate::graph::Hypergraph; -use crate::graph::kind::GraphKind; -use crate::graph::vertex::child::Child; -use crate::graph::vertex::data::VertexData; -use crate::graph::vertex::key::VertexKey; -use crate::graph::vertex::token::{AsToken, Token}; -use crate::graph::vertex::{IndexPattern, VertexIndex}; -use crate::graph::vertex::pattern::{IntoPattern, Pattern}; -use crate::search::NoMatch; +use crate::{ + graph::{ + getters::vertex::VertexSet, + kind::GraphKind, + vertex::{ + child::Child, + data::VertexData, + key::VertexKey, + pattern::{ + IntoPattern, + Pattern, + }, + token::{ + AsToken, + Token, + }, + IndexPattern, + VertexIndex, + }, + Hypergraph, + }, + search::NoMatch, +}; impl Hypergraph { pub fn get_token_data( &self, token: &Token, ) -> Result<&VertexData, NoMatch> { - self.get_vertex( - self.get_token_index(token)? - ) + self.get_vertex(self.get_token_index(token)?) } pub fn get_token_data_mut( &mut self, token: &Token, ) -> Result<&mut VertexData, NoMatch> { - self.get_vertex_mut( - self.get_token_index(token)? - ) + self.get_vertex_mut(self.get_token_index(token)?) } pub fn get_token_index( &self, token: impl AsToken, ) -> Result { - Ok( - self.graph.get_index_of(&self.get_token_key(token.as_token())?) - .unwrap() - ) + Ok(self + .graph + .get_index_of(&self.get_token_key(token.as_token())?) + .unwrap()) } pub fn get_token_key( &self, token: impl AsToken, ) -> Result { - self.token_keys.get(&token.as_token()) - .copied().ok_or(NoMatch::UnknownToken) + self.token_keys + .get(&token.as_token()) + .copied() + .ok_or(NoMatch::UnknownToken) } pub fn get_token_child( &self, @@ -74,7 +85,8 @@ impl Hypergraph { &'a self, tokens: impl IntoIterator> + 'a, ) -> impl Iterator> + 'a { - tokens.into_iter() + tokens + .into_iter() .map(move |token| self.get_token_index(token)) } pub fn to_token_children_iter<'a>( @@ -119,4 +131,4 @@ impl Hypergraph { self.get_token_indices(tokens) .expect("Failed to convert tokens to indices") } -} \ No newline at end of file +} diff --git a/seqraph/src/graph/mod.rs b/seqraph/src/graph/mod.rs index 0f02b7c..a26167d 100644 --- a/seqraph/src/graph/mod.rs +++ b/seqraph/src/graph/mod.rs @@ -316,6 +316,12 @@ where self.get_token_by_key(key) .expect("Key does not belong to a token!") } + pub fn vertex_key_string( + &self, + key: &VertexKey, + ) -> String { + self.vertex_data_string(self.expect_vertex(key)) + } pub fn vertex_data_string( &self, data: &VertexData, diff --git a/seqraph/src/graph/vertex/data.rs b/seqraph/src/graph/vertex/data.rs index 3858100..30d8203 100644 --- a/seqraph/src/graph/vertex/data.rs +++ b/seqraph/src/graph/vertex/data.rs @@ -1,61 +1,80 @@ -use std::{ - fmt::Debug, - num::NonZeroUsize, - slice::SliceIndex, -}; -use std::fmt::Display; use derive_builder::Builder; use either::Either; +use itertools::Itertools; use serde::{ Deserialize, Serialize, }; +use std::{ + fmt::{ + Debug, + Display, + }, + num::NonZeroUsize, + slice::SliceIndex, +}; use crate::{ - graph::kind::GraphKind, - HashSet, - search::NoMatch, -}; -use crate::graph::vertex::{ - child::Child, - has_vertex_index::HasVertexIndex, - location::{ - child::ChildLocation, - SubLocation, + graph::{ + kind::GraphKind, + vertex::{ + child::Child, + has_vertex_index::{ + HasVertexIndex, + ToChild, + }, + key::VertexKey, + location::{ + child::ChildLocation, + SubLocation, + }, + parent::{ + Parent, + PatternIndex, + }, + pattern::{ + self, + pattern_range::PatternRangeIndex, + pattern_width, + IntoPattern, + Pattern, + }, + wide::Wide, + ChildPatterns, + IndexPosition, + PatternId, + TokenPosition, + VertexIndex, + VertexParents, + }, + Hypergraph, }, - parent::PatternIndex, - pattern::{ - IntoPattern, - pattern_range::PatternRangeIndex, - pattern_width, - }, - wide::Wide, + search::NoMatch, + HashSet, }; -use crate::graph::vertex::{ChildPatterns, IndexPosition, pattern, PatternId, TokenPosition, VertexIndex, VertexParents}; -use crate::graph::vertex::has_vertex_index::ToChild; -use crate::graph::vertex::parent::Parent; -use crate::graph::vertex::pattern::Pattern; -use crate::graph::Hypergraph; -use crate::graph::vertex::key::VertexKey; -pub fn clone_child_patterns(children: &'_ ChildPatterns) -> impl Iterator + '_ { +pub fn clone_child_patterns( + children: &'_ ChildPatterns +) -> impl Iterator + '_ +{ children.iter().map(|(_, p)| p.clone()) } -pub fn localized_children_iter_for_index(parent: impl ToChild, children: &ChildPatterns) -> impl IntoIterator +pub fn localized_children_iter_for_index( + parent: impl ToChild, + children: &ChildPatterns, +) -> impl IntoIterator { let parent = parent.to_child(); - children.iter().flat_map(move |(&pid, pat)| - pat.iter().enumerate() - .map(move |(i, c)| ( - ChildLocation::new(parent, pid, i), - c, - )) - ) + children.iter().flat_map(move |(&pid, pat)| { + pat.iter() + .enumerate() + .map(move |(i, c)| (ChildLocation::new(parent, pid, i), c)) + }) } #[derive(Debug, PartialEq, Eq, Clone, Builder, Serialize, Deserialize)] -pub struct VertexData { - +pub struct VertexData +{ pub width: TokenPosition, pub index: VertexIndex, @@ -69,11 +88,13 @@ pub struct VertexData { pub children: ChildPatterns, } -impl VertexData { +impl VertexData +{ pub fn new( index: VertexIndex, width: TokenPosition, - ) -> Self { + ) -> Self + { Self { width, key: VertexKey::default(), @@ -82,13 +103,15 @@ impl VertexData { children: ChildPatterns::default(), } } - pub fn get_width(&self) -> TokenPosition { + pub fn get_width(&self) -> TokenPosition + { self.width } pub fn get_parent( &self, index: impl HasVertexIndex, - ) -> Result<&Parent, NoMatch> { + ) -> Result<&Parent, NoMatch> + { let index = index.vertex_index(); self.parents .get(&index) @@ -97,7 +120,8 @@ impl VertexData { pub fn get_parent_mut( &mut self, index: impl HasVertexIndex, - ) -> Result<&mut Parent, NoMatch> { + ) -> Result<&mut Parent, NoMatch> + { let index = index.vertex_index(); self.parents .get_mut(&index) @@ -107,36 +131,47 @@ impl VertexData { pub fn expect_parent( &self, index: impl HasVertexIndex, - ) -> &Parent { + ) -> &Parent + { self.get_parent(index).unwrap() } #[track_caller] pub fn expect_parent_mut( &mut self, index: impl HasVertexIndex, - ) -> &mut Parent { + ) -> &mut Parent + { self.get_parent_mut(index).unwrap() } - pub fn get_parents(&self) -> &VertexParents { + pub fn get_parents(&self) -> &VertexParents + { &self.parents } - pub fn get_parents_mut(&mut self) -> &mut VertexParents { + pub fn get_parents_mut(&mut self) -> &mut VertexParents + { &mut self.parents } pub fn get_child_pattern_range( &self, id: &PatternId, range: R, - ) -> Result<&>::Output, NoMatch> { - self.get_child_pattern(id) - .and_then(|p| pattern::pattern_range::get_child_pattern_range(id, p, range.clone())) + ) -> Result<&>::Output, NoMatch> + { + self.get_child_pattern(id).and_then(|p| { + pattern::pattern_range::get_child_pattern_range( + id, + p, + range.clone(), + ) + }) } #[track_caller] pub fn expect_child_pattern_range( &self, id: &PatternId, range: R, - ) -> &>::Output { + ) -> &>::Output + { let p = self.expect_child_pattern(id); pattern::pattern_range::get_child_pattern_range(id, p, range.clone()) .expect("Range in pattern") @@ -145,7 +180,8 @@ impl VertexData { &self, id: &PatternId, pos: IndexPosition, - ) -> Result<&Child, NoMatch> { + ) -> Result<&Child, NoMatch> + { self.children .get(id) .and_then(|p| p.get(pos)) @@ -154,7 +190,8 @@ impl VertexData { pub fn get_child_pattern_with_prefix_width( &self, width: NonZeroUsize, - ) -> Option<(&PatternId, &Pattern)> { + ) -> Option<(&PatternId, &Pattern)> + { self.children .iter() .find(|(_pid, pat)| pat[0].width() == width.get()) @@ -162,13 +199,15 @@ impl VertexData { pub fn get_child_pattern( &self, id: &PatternId, - ) -> Result<&Pattern, NoMatch> { + ) -> Result<&Pattern, NoMatch> + { self.children.get(id).ok_or(NoMatch::InvalidPattern(*id)) } pub fn get_child_at( &self, location: &SubLocation, - ) -> Result<&Child, NoMatch> { + ) -> Result<&Child, NoMatch> + { self.children .get(&location.pattern_id) .ok_or(NoMatch::InvalidPattern(location.pattern_id))? @@ -178,13 +217,15 @@ impl VertexData { pub fn expect_child_at( &self, location: &SubLocation, - ) -> &Child { + ) -> &Child + { self.get_child_at(location).unwrap() } pub fn get_child_mut_at( &mut self, location: &SubLocation, - ) -> Result<&mut Child, NoMatch> { + ) -> Result<&mut Child, NoMatch> + { self.children .get_mut(&location.pattern_id) .ok_or(NoMatch::InvalidPattern(location.pattern_id))? @@ -194,46 +235,54 @@ impl VertexData { pub fn expect_child_mut_at( &mut self, location: &SubLocation, - ) -> &mut Child { + ) -> &mut Child + { self.get_child_mut_at(location).unwrap() } #[track_caller] pub fn expect_pattern_len( &self, id: &PatternId, - ) -> usize { + ) -> usize + { self.expect_child_pattern(id).len() } pub fn expect_child_offset( &self, loc: &SubLocation, - ) -> usize { - pattern_width(&self.expect_child_pattern(&loc.pattern_id)[0..loc.sub_index]) + ) -> usize + { + pattern_width( + &self.expect_child_pattern(&loc.pattern_id)[0..loc.sub_index], + ) } pub fn find_child_pattern_id( &self, f: impl FnMut(&(&PatternId, &Pattern)) -> bool, - ) -> Option { + ) -> Option + { self.children.iter().find(f).map(|r| *r.0) } pub fn get_child_pattern_mut( &mut self, id: &PatternId, - ) -> Result<&mut Pattern, NoMatch> { + ) -> Result<&mut Pattern, NoMatch> + { self.children.get_mut(id).ok_or(NoMatch::NoChildPatterns) } #[track_caller] - pub fn expect_any_child_pattern(&self) -> (&PatternId, &Pattern) { - self.children - .iter() - .next() - .unwrap_or_else(|| panic!("Pattern vertex has no children {:#?}", self,)) + pub fn expect_any_child_pattern(&self) -> (&PatternId, &Pattern) + { + self.children.iter().next().unwrap_or_else(|| { + panic!("Pattern vertex has no children {:#?}", self,) + }) } #[track_caller] pub fn expect_child_pattern( &self, id: &PatternId, - ) -> &Pattern { + ) -> &Pattern + { self.get_child_pattern(id).unwrap_or_else(|_| { panic!( "Child pattern with id {} does not exist in in vertex {:#?}", @@ -245,31 +294,42 @@ impl VertexData { pub fn expect_child_pattern_mut( &mut self, id: &PatternId, - ) -> &mut Pattern { - self.get_child_pattern_mut(id) - .unwrap_or_else(|_| panic!("Child pattern with id {} does not exist in in vertex", id,)) + ) -> &mut Pattern + { + self.get_child_pattern_mut(id).unwrap_or_else(|_| { + panic!("Child pattern with id {} does not exist in in vertex", id,) + }) } - pub fn get_child_patterns(&self) -> &ChildPatterns { + pub fn get_child_patterns(&self) -> &ChildPatterns + { &self.children } - pub fn get_child_patterns_mut(&mut self) -> &mut ChildPatterns { + pub fn get_child_patterns_mut(&mut self) -> &mut ChildPatterns + { &mut self.children } - pub fn get_child_pattern_iter(&'_ self) -> impl Iterator + '_ { + pub fn get_child_pattern_iter( + &'_ self + ) -> impl Iterator + '_ + { clone_child_patterns(&self.children) } - pub fn get_child_pattern_set(&self) -> HashSet { + pub fn get_child_pattern_set(&self) -> HashSet + { self.get_child_pattern_iter().collect() } - pub fn get_child_pattern_vec(&self) -> Vec { + pub fn get_child_pattern_vec(&self) -> Vec + { self.get_child_pattern_iter().collect() } pub fn add_pattern_no_update( &mut self, id: PatternId, pat: impl IntoPattern, - ) { - if pat.borrow().len() < 2 { + ) + { + if pat.borrow().len() < 2 + { assert!(pat.borrow().len() > 1); } self.children.insert(id, pat.into_pattern()); @@ -278,9 +338,12 @@ impl VertexData { pub fn add_patterns_no_update( &mut self, patterns: impl IntoIterator, - ) { - for (id, pat) in patterns { - if pat.borrow().len() < 2 { + ) + { + for (id, pat) in patterns + { + if pat.borrow().len() < 2 + { assert!(pat.borrow().len() > 1); } self.children.insert(id, pat.into_pattern()); @@ -288,14 +351,16 @@ impl VertexData { self.validate(); } #[track_caller] - pub fn validate_links(&self) { + pub fn validate_links(&self) + { assert!(self.children.len() != 1 || self.parents.len() != 1); } #[track_caller] - pub fn validate_patterns(&self) { - self.children - .iter() - .fold(Vec::new(), |mut acc: Vec>, (_pid, p)| { + pub fn validate_patterns(&self) + { + self.children.iter().fold( + Vec::new(), + |mut acc: Vec>, (_pid, p)| { let mut offset = 0; assert!(!p.is_empty()); let mut p = p.iter().fold(Vec::new(), |mut pa, c| { @@ -312,22 +377,29 @@ impl VertexData { assert_eq!(offset, self.width); acc.push(p); acc - }); + }, + ); } #[track_caller] - pub fn validate(&self) { + pub fn validate(&self) + { //self.validate_links(); - if !self.children.is_empty() { + if !self.children.is_empty() + { self.validate_patterns(); } } pub fn add_parent( &mut self, loc: ChildLocation, - ) { - if let Some(parent) = self.parents.get_mut(&loc.parent.vertex_index()) { + ) + { + if let Some(parent) = self.parents.get_mut(&loc.parent.vertex_index()) + { parent.add_pattern_index(loc.pattern_id, loc.sub_index); - } else { + } + else + { let mut parent_rel = Parent::new(loc.parent.width()); parent_rel.add_pattern_index(loc.pattern_id, loc.sub_index); self.parents.insert(loc.parent.vertex_index(), parent_rel); @@ -338,7 +410,8 @@ impl VertexData { pub fn remove_parent( &mut self, vertex: impl HasVertexIndex, - ) { + ) + { self.parents.remove(&vertex.vertex_index()); // not while indexing //self.validate_links(); @@ -348,11 +421,16 @@ impl VertexData { vertex: impl HasVertexIndex, pattern: PatternId, index: usize, - ) { - if let Some(parent) = self.parents.get_mut(&vertex.vertex_index()) { - if parent.pattern_indices.len() > 1 { + ) + { + if let Some(parent) = self.parents.get_mut(&vertex.vertex_index()) + { + if parent.pattern_indices.len() > 1 + { parent.remove_pattern_index(pattern, index); - } else { + } + else + { self.parents.remove(&vertex.vertex_index()); } } @@ -362,16 +440,20 @@ impl VertexData { pub fn get_parents_below_width( &self, width_ceiling: Option, - ) -> impl Iterator + Clone { + ) -> impl Iterator + Clone + { let parents = self.get_parents(); // optionally filter parents by width - if let Some(ceil) = width_ceiling { + if let Some(ceil) = width_ceiling + { Either::Left( parents .iter() .filter(move |(_, parent)| parent.get_width() < ceil), ) - } else { + } + else + { Either::Right(parents.iter()) } } @@ -446,7 +528,8 @@ impl VertexData { &self, parent_index: impl HasVertexIndex, index_offset: usize, - ) -> Result { + ) -> Result + { let index = parent_index.vertex_index(); self.get_parent(index) .ok() @@ -456,13 +539,15 @@ impl VertexData { pub fn get_parent_at_prefix_of( &self, index: impl HasVertexIndex, - ) -> Result { + ) -> Result + { self.get_parent_to_starting_at(index, 0) } pub fn get_parent_at_postfix_of( &self, vertex: &VertexData, - ) -> Result { + ) -> Result + { self.get_parent(vertex.vertex_index()) .ok() .and_then(|parent| parent.get_index_at_postfix_of(vertex)) @@ -484,31 +569,53 @@ impl VertexData { // }) // .ok_or(NoMatch::NoChildPatterns) //} - pub fn largest_postfix(&self) -> (PatternId, Child) { + pub fn largest_postfix(&self) -> (PatternId, Child) + { let (id, c) = self .children .iter() .fold(None, |acc: Option<(&PatternId, &Child)>, (pid, p)| { - if let Some(acc) = acc { + if let Some(acc) = acc + { let c = p.last().unwrap(); - if c.width() > acc.1.width() { + if c.width() > acc.1.width() + { Some((pid, c)) - } else { + } + else + { Some(acc) } - } else { + } + else + { Some((pid, p.last().unwrap())) } }) .unwrap(); (*id, *c) } - pub fn all_children_iter(&self) -> impl IntoIterator{ - self.children.iter().flat_map(|(_, pat)| - pat.iter() - ) + pub fn all_children_iter(&self) -> impl IntoIterator + { + self.children.iter().flat_map(|(_, pat)| pat.iter()) } - pub fn all_localized_children_iter(&self) -> impl IntoIterator{ + pub fn all_localized_children_iter( + &self + ) -> impl IntoIterator + { localized_children_iter_for_index(self.to_child(), &self.children) } + pub fn top_down_containment_nodes(&self) -> Vec<(usize, Child)> + { + self.children + .iter() + .flat_map(|(_, pat)| { + pat.iter() + .enumerate() + .filter(|(_, c)| c.width() + 1 == self.width()) + .map(|(off, c)| (off, *c)) + }) + .sorted_by_key(|&(off, _)| off) + .collect_vec() + } } diff --git a/seqraph/src/graph/vertex/has_vertex_data.rs b/seqraph/src/graph/vertex/has_vertex_data.rs index d5e90fe..5af99e4 100644 --- a/seqraph/src/graph/vertex/has_vertex_data.rs +++ b/seqraph/src/graph/vertex/has_vertex_data.rs @@ -5,14 +5,29 @@ use std::ops::{ use crate::graph::getters::vertex::VertexSet; use crate::graph::vertex::child::Child; +use crate::graph::vertex::has_vertex_index::HasVertexIndex; +use crate::graph::vertex::key::VertexKey; use crate::graph::{ Hypergraph, kind::GraphKind, }; use crate::graph::vertex::data::VertexData; -use crate::graph::vertex::has_vertex_index::ToChild; pub trait HasVertexDataMut: HasVertexData { + fn vertex_mut<'a, G: GraphKind + 'a, R: Deref> + DerefMut>( + self, + graph: &'a mut R, + ) -> &'a mut VertexData + where + Self: 'a; + + fn vertex_ref_mut<'a, G: GraphKind + 'a, R: Deref> + DerefMut>( + &'a mut self, + graph: &'a mut R, + ) -> &'a mut VertexData; +} + +impl HasVertexDataMut for Child { fn vertex_mut<'a, G: GraphKind + 'a, R: Deref> + DerefMut>( self, graph: &'a mut R, @@ -30,8 +45,6 @@ pub trait HasVertexDataMut: HasVertexData { } } -impl HasVertexDataMut for Child {} - impl HasVertexDataMut for &'_ mut V { fn vertex_mut<'a, G: GraphKind + 'a, R: Deref> + DerefMut>( self, @@ -66,7 +79,20 @@ impl HasVertexDataMut for &'_ mut V { // } //} -pub trait HasVertexData: ToChild + Sized { +pub trait HasVertexData: Sized { + fn vertex<'a, G: GraphKind + 'a, R: Deref>>( + self, + graph: &'a R, + ) -> &'a VertexData + where + Self: 'a; + fn vertex_ref<'a, G: GraphKind + 'a, R: Deref>>( + &'a self, + graph: &'a R, + ) -> &'a VertexData; +} + +impl HasVertexData for Child { fn vertex<'a, G: GraphKind + 'a, R: Deref>>( self, graph: &'a R, @@ -83,8 +109,23 @@ pub trait HasVertexData: ToChild + Sized { graph.expect_vertex(self.vertex_index()) } } - -impl HasVertexData for Child {} +impl HasVertexData for VertexKey { + fn vertex<'a, G: GraphKind + 'a, R: Deref>>( + self, + graph: &'a R, + ) -> &'a VertexData + where + Self: 'a, + { + graph.expect_vertex(self) + } + fn vertex_ref<'a, G: GraphKind + 'a, R: Deref>>( + &'a self, + graph: &'a R, + ) -> &'a VertexData { + graph.expect_vertex(self) + } +} impl HasVertexData for &'_ V { fn vertex<'a, G: GraphKind + 'a, R: Deref>>( diff --git a/seqraph/src/graph/vertex/parent.rs b/seqraph/src/graph/vertex/parent.rs index 68a660d..13098c7 100644 --- a/seqraph/src/graph/vertex/parent.rs +++ b/seqraph/src/graph/vertex/parent.rs @@ -1,3 +1,4 @@ +use crate::graph::vertex::wide::Wide; use crate::{ HashMap, HashSet, @@ -39,7 +40,11 @@ pub struct Parent { /// positions of child in parent patterns pub pattern_indices: HashSet, } - +impl Wide for Parent { + fn width(&self) -> usize { + self.width + } +} impl Parent { pub fn new(width: TokenPosition) -> Self { Self { diff --git a/src/graph/mod.rs b/src/graph/mod.rs index da39678..8974bd8 100644 --- a/src/graph/mod.rs +++ b/src/graph/mod.rs @@ -45,7 +45,7 @@ impl Graph let new = Self { graph, vis, - insert_text: String::from("heldldo"), + insert_text: String::from("ababa"), }; let g = new.clone(); new.vis_mut().set_graph(g); @@ -83,10 +83,10 @@ impl Graph { *self = Self::default(); } - pub fn read_text(&mut self, text: impl ToString, ctx: &egui::Context) -> JoinHandle<()> { - let text = text.to_string(); + pub fn read_text(&mut self, _text: impl ToString, ctx: &egui::Context) -> JoinHandle<()> { + //let text = text.to_string(); let ctx = ctx.clone(); - let mut graph = self.graph.clone(); + //let mut graph = self.graph.clone(); tokio::task::spawn_blocking(move || { //graph.read_sequence(text.chars()); println!("done reading"); diff --git a/src/graph/vis.rs b/src/graph/vis.rs index b99d162..d71f007 100644 --- a/src/graph/vis.rs +++ b/src/graph/vis.rs @@ -24,7 +24,7 @@ use seqraph::graph::{vertex::{child::Child, data::VertexData, has_vertex_index:: use std::{collections::HashMap, sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard}}; use std::f32::consts::PI; -use crate::Graph; +use crate::graph::Graph; #[derive(Debug, Clone, PartialEq)] pub enum Layout diff --git a/src/lib.rs b/src/lib.rs index 232878f..3f111be 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,8 +16,6 @@ use eframe::wasm_bindgen::{ use seqraph::graph::HypergraphRef; pub use tracing::*; pub use { - graph::*, - seqraph::*, std::sync::{ Arc, RwLock, diff --git a/src/main.rs b/src/main.rs index b2a4418..498c455 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,8 +8,6 @@ mod graph; pub use tracing::*; pub use { - graph::*, - seqraph::*, std::sync::{ Arc, RwLock,