summaryrefslogtreecommitdiff
path: root/chain/src/item/genins.rs
diff options
context:
space:
mode:
Diffstat (limited to 'chain/src/item/genins.rs')
-rw-r--r--chain/src/item/genins.rs103
1 files changed, 81 insertions, 22 deletions
diff --git a/chain/src/item/genins.rs b/chain/src/item/genins.rs
index 0c3f616..97d7ba9 100644
--- a/chain/src/item/genins.rs
+++ b/chain/src/item/genins.rs
@@ -190,7 +190,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
let root = if let Some(root) = self.root() {
root
} else {
- panic!("the forest must be non-empty when we insert items");
+ unreachable!("the forest must be non-empty when we insert items");
};
let pavi = label.forest_source();
@@ -211,13 +211,50 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
let pos = fragment_root_label.label().start();
+ dbg!((pos, label));
+
+ let tnt_string = {
+ let empty_p = atom_child_iter.len() == 0;
+ let label = fragment.vertex_label(fragment.nodes_len() - 1)?.unwrap();
+
+ match label.label().label() {
+ GrammarLabelType::TNT(TNT::Ter(t)) => {
+ format!("t {t}")
+ }
+ GrammarLabelType::TNT(TNT::Non(n)) => {
+ format!("n {n} {}", if empty_p { "second" } else { "first" })
+ }
+ _ => "error".to_string(),
+ }
+ };
+
+ let num = {
+ let mut repetition = 0;
+
+ while std::fs::metadata(format!(
+ "/Users/durand/Desktop/Centre/A propos de programmes/Rust/rep/chain/output/pos {pos} {tnt_string} {repetition}.gv"
+ ))
+ .is_ok()
+ {
+ repetition += 1;
+ }
+
+ repetition
+ };
+
+ self.print_viz(&format!("pos {pos} {tnt_string} {num}.gv"))
+ .unwrap();
+
self.extra_reductions(
- BoTop::new(pavi, true_source),
+ BoTop::new(true_source, pavi),
pos,
reducer.borrow(),
atom.borrow(),
)?;
+ self.print_viz(&format!("pos {pos} {tnt_string} {num} stage 1.gv"))
+ .unwrap();
+
// Ensure the last node in the PaVi is a terminal or a
// non-terminal node, as an extra safety guard during
// development.
@@ -259,6 +296,8 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
}
}
+ // TODO: Print each and every step.
+
// TODO: Refactor this.
let is_empty_segment = pavi.is_empty();
@@ -290,15 +329,19 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
.vertex_label(frag_nodes_len - 2)?
.ok_or(Error::NodeNoLabel(frag_nodes_len - 2))?;
- // NOTE: The function
- // `plant_if_needed` assumes that we
- // want to plant the fragment as the
- // first child of the node. This
- // assumption holds in this case, but
- // not in general.
+ // NOTE: The function `plant_at_start`
+ // assumes that we want to plant the
+ // fragment as the first child of the
+ // node. This assumption holds in
+ // this case, but not in general.
self.plant_at_start(node, frag)?;
+ self.print_viz(&format!(
+ "pos {pos} {tnt_string} {num} stage 1.5 {node}.gv"
+ ))
+ .unwrap();
+
let rule_label_pos = self
.query_label(last_but_one_label)
.expect("the forest was wrongly planted");
@@ -370,6 +413,13 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
let sploned_node =
self.splone(node.node(), Some(pos), node.edge(), false)?;
+ self.print_viz(&format!(
+ "pos {pos} {tnt_string} {num} stage 2 {} {}.gv",
+ node.node(),
+ node.edge(),
+ ))
+ .unwrap();
+
node_label = self
.vertex_label(sploned_node)?
.ok_or(Error::NodeNoLabel(sploned_node))?;
@@ -394,9 +444,11 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
let parents_iter = self.parents_of(node.node())?;
for parent in parents_iter {
+ let parent_node = parent.node();
+
let parent_label = self
- .vertex_label(parent.node())?
- .ok_or_else(|| Error::NodeNoLabel(parent.node()))?
+ .vertex_label(parent_node)?
+ .ok_or(Error::NodeNoLabel(parent_node))?
.label();
if parent_label.label().rule().is_none() {
@@ -448,15 +500,15 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
return Err(Error::CannotPlant);
}
- if pos == 4 && matches!(true_source, PaVi::Virtual(_, _, _)) {
- dbg!(&stack, reduction_info, true_source, pavi);
- self.print_viz("pos4ib.gv").unwrap();
- }
-
for parent in stack {
- let sploned_node = self.splone(parent.node(), None, parent.edge(), false)?;
+ let splanted = self.splant(parent.node(), parent.edge(), fragment, non_empty)?;
- self.plant(sploned_node, fragment, non_empty)?;
+ self.print_viz(&format!(
+ "pos {pos} {tnt_string} {num} stage 3 {} {} {splanted}.gv",
+ parent.node(),
+ parent.edge(),
+ ))
+ .unwrap();
non_empty = true;
}
@@ -533,12 +585,14 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
}
};
- let t = match root_label.label().label().tnt().unwrap() {
+ let error_str = "a virtual fragment should consist of a single terminal node";
+
+ let t = match root_label.label().label().tnt().expect(error_str) {
TNT::Ter(t) => t,
_ => {
dbg!(root_label);
- panic!("a virtual fragment should consist of a single terminal node")
+ panic!("{error_str}")
}
};
@@ -550,7 +604,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
/// Perform extra reductions.
///
- /// To be precise, this functions first splones the bottom node,
+ /// To be precise, this function first splones the bottom node,
/// and then queries the reducer to find the next nodes to splone,
/// and repeats this process until either we find the top node, or
/// the reducer says to stop.
@@ -583,6 +637,9 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
let mut stack = vec![bottom_node];
+ // Exclude duplicate nodes to ensure that no infinite
+ // recursion occurs. In the future I shall experiment if this
+ // is necessary, and get rid of this if possible.
let mut seen_nodes: HashSet<usize> = Default::default();
let mut result = Vec::new();
@@ -683,6 +740,8 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
// REVIEW: is this really correct?
dbg!("this should not really happen?");
+ // SUMMARY: splone every child of nth_child
+
let mut result: usize = nth_child;
for node in self.children_of(nth_child)?.collect::<Vec<_>>() {
@@ -806,8 +865,8 @@ mod genins_test {
assert!(matches!(atom.query_reduction(17, 9), Ok(Some(&[1]))));
- assert!(matches!(atom.query_reduction(35, 9), Ok(Some(&[1, 2]))));
- assert!(matches!(atom.query_reduction(35, 25), Ok(Some(&[2]))));
+ // assert!(matches!(atom.query_reduction(35, 9), Ok(Some(&[1, 2]))));
+ // assert!(matches!(atom.query_reduction(35, 25), Ok(Some(&[2]))));
Ok(())
}