summaryrefslogtreecommitdiff
path: root/chain/src/atom/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'chain/src/atom/mod.rs')
-rw-r--r--chain/src/atom/mod.rs28
1 files changed, 28 insertions, 0 deletions
diff --git a/chain/src/atom/mod.rs b/chain/src/atom/mod.rs
index 398edd2..c9dadb2 100644
--- a/chain/src/atom/mod.rs
+++ b/chain/src/atom/mod.rs
@@ -17,6 +17,16 @@ pub trait Atom: Nfa<LabelType<TNT>> + Deref<Target = Grammar> {
/// left-linear null closure of `nt` with respect to `t`.
fn atom(&self, nt: usize, t: usize) -> Result<Option<usize>, GrammarError>;
+ /// A type that iterates through the rule positions.
+ type Iter<'a>: Iterator<Item = usize> + 'a
+ where
+ Self: 'a;
+
+ /// Return an iterator of rule positions responsible for an edge
+ /// from the virtual node corresponding to the non-terminal `nt`
+ /// and terminal `t` to `target`.
+ fn trace(&self, nt: usize, t: usize, target: usize) -> Option<<Self as Atom>::Iter<'_>>;
+
/// Return the index of the empty state.
fn empty(&self) -> usize;
@@ -33,6 +43,9 @@ mod tests {
use super::*;
use grammar::test_grammar_helper::*;
+ #[cfg(feature = "test-print-viz")]
+ use graph::Graph;
+
#[test]
fn atom() -> Result<(), Box<dyn std::error::Error>> {
let grammar = new_notes_grammar()?;
@@ -41,6 +54,21 @@ mod tests {
println!("atom = {atom}");
+ #[cfg(feature = "test-print-viz")]
+ {
+ println!("virtual frag for 1, 3: ");
+
+ for (index, frag) in atom
+ .generate_virtual_frags(1, 3, None)
+ .iter()
+ .flatten()
+ .enumerate()
+ {
+ crate::item::default::print_labels(&atom, *frag)?;
+ frag.print_viz(&format!("frag {index}.gv"))?;
+ }
+ }
+
Ok(())
}
}