From 57d600f261cca5d9076239e548c6e00646f774b6 Mon Sep 17 00:00:00 2001 From: JSDurand Date: Thu, 2 Mar 2023 15:50:56 +0800 Subject: extra reductions Finished the function of performing extra reductions. Still untested though. --- chain/src/default.rs | 55 ++++++++++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 25 deletions(-) (limited to 'chain/src/default.rs') 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>; +/// 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>; /// 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, &'a DefaultAtom, &'a [bool], PaVi, PaVi); + /// `(graph, atom, forest, accepting_vec, forest_source, new_source)` + type GeneratorInput<'a> = ( + &'a DLGraph, + &'a DefaultAtom, + &'a DefaultForest>, + &'a [bool], + PaVi, + PaVi, + ); /// A helper function to generate edges to join. /// @@ -575,7 +581,7 @@ impl Chain for DefaultChain { ) -> Result { 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)?); } } } -- cgit v1.2.3-18-g5258