summaryrefslogtreecommitdiff
path: root/chain/src/default.rs
diff options
context:
space:
mode:
Diffstat (limited to 'chain/src/default.rs')
-rw-r--r--chain/src/default.rs55
1 files changed, 30 insertions, 25 deletions
diff --git a/chain/src/default.rs b/chain/src/default.rs
index 6e935fe..1df68b5 100644
--- a/chain/src/default.rs
+++ b/chain/src/default.rs
@@ -214,17 +214,16 @@ pub(crate) struct BoTop {
top: PaVi,
}
-#[allow(dead_code)]
impl BoTop {
- fn new(bottom: PaVi, top: PaVi) -> Self {
+ pub(crate) fn new(bottom: PaVi, top: PaVi) -> Self {
Self { bottom, top }
}
- fn top(&self) -> PaVi {
+ pub(crate) fn top(&self) -> PaVi {
self.top
}
- fn bottom(&self) -> PaVi {
+ pub(crate) fn bottom(&self) -> PaVi {
self.bottom
}
}
@@ -240,10 +239,10 @@ impl BoTop {
/// # Reduction format
///
/// The value records a set of tuples of the form `(non-terminal,
-/// rule_position)`. Such a tuple means we want to reduce from the
-/// expansion of the given `non-terminal`, where the last rule
-/// position we have seen in this branch is the given `rule_position`.
-type Reducer = Map<BoTop, HashSet<(usize, usize)>>;
+/// starting_position)`. Such a tuple means we want to reduce from
+/// the expansion of the given `non-terminal`, which expands from the
+/// given starting position. We need to restrict the
+pub(crate) type Reducer = Map<(usize, usize), HashSet<usize>>;
/// A default implementation for the [`Chain`] trait.
#[derive(Debug, Clone, Default)]
@@ -553,8 +552,15 @@ impl Chain for DefaultChain {
///
/// The format is as follows:
///
- /// `(graph, atom, accepting_vec, forest_source, new_source)`
- type GeneratorInput<'a> = (&'a DLGraph<Edge>, &'a DefaultAtom, &'a [bool], PaVi, PaVi);
+ /// `(graph, atom, forest, accepting_vec, forest_source, new_source)`
+ type GeneratorInput<'a> = (
+ &'a DLGraph<Edge>,
+ &'a DefaultAtom,
+ &'a DefaultForest<ForestLabel<GrammarLabel>>,
+ &'a [bool],
+ PaVi,
+ PaVi,
+ );
/// A helper function to generate edges to join.
///
@@ -575,7 +581,7 @@ impl Chain for DefaultChain {
) -> Result<bool, Error> {
let mut accepting = false;
- let (graph, atom, accepting_vec, pavi, true_pavi) = input;
+ let (graph, atom, forest, accepting_vec, pavi, true_pavi) = input;
// First check the values from iterators are all valid.
let graph_len = graph.nodes_len();
@@ -644,21 +650,15 @@ impl Chain for DefaultChain {
let botop = BoTop::new(true_pavi, new_label.forest_source());
- let rule_pos = child_label.label().div_euclid(2);
-
- let rule_nt = atom
- .get_rule_num(rule_pos)
- .map_err(index_out_of_bounds_conversion)?;
-
- let rule_pos = rule_pos
- - atom
- .nth_accumulator(rule_nt)
- .map_err(index_out_of_bounds_conversion)?;
+ let key = (
+ forest.node_from_pavi(botop.top())?,
+ forest.node_from_pavi(botop.bottom)?,
+ );
reducer
- .entry(botop)
+ .entry(key)
.or_insert_with(Default::default)
- .insert((rule_nt, rule_pos));
+ .insert(forest.node_from_pavi(new_label.true_source())?);
output.extend(
std::iter::repeat(new_label.into())
@@ -714,6 +714,7 @@ impl Chain for DefaultChain {
}
new_pavi = self.forest.insert_item(
+ &self.reducer,
*label,
fragment,
atom_child_iter.clone(),
@@ -735,6 +736,7 @@ impl Chain for DefaultChain {
let generator_input = (
&self.graph,
&self.atom,
+ &self.forest,
self.accepting_vec.as_slice(),
new_pavi,
new_pavi,
@@ -787,6 +789,7 @@ impl Chain for DefaultChain {
}
first_segment_pavi = self.forest.insert_item(
+ &self.reducer,
*label,
first_fragment,
atom_child_iter.clone(),
@@ -807,6 +810,7 @@ impl Chain for DefaultChain {
// iterator, in which case the passed
// label is only used for the PaVi.
virtual_pavi = self.forest.insert_item(
+ &self.reducer,
Edge::new(0, first_segment_pavi, accepting),
virtual_fragment,
std::iter::empty(),
@@ -828,6 +832,7 @@ impl Chain for DefaultChain {
let generator_input = (
&self.graph,
&self.atom,
+ &self.forest,
self.accepting_vec.as_slice(),
first_segment_pavi,
virtual_pavi,
@@ -980,9 +985,9 @@ impl Chain for DefaultChain {
for frag in reduction_fragment.into_iter().flatten() {
let mut frag = frag.clone();
- frag.set_pos(node_label.label().start())?;
+ frag.set_pos(node_label.label().start(), true)?;
- stack.push(self.forest.plant_if_needed(*node, frag)?);
+ stack.push(self.forest.plant_at_start(*node, frag)?);
}
}
}