aboutsummaryrefslogtreecommitdiff
path: root/chain
diff options
context:
space:
mode:
authorJSDurand <mmemmew@gmail.com>2026-10-16 14:01:01 +0800
committerJSDurand <mmemmew@gmail.com>2026-10-16 14:02:10 +0800
commitfba9a90cfc6aca2a26cce72f55fb261789139781 (patch)
treeb4b121791ad639e745df689c0d5a8ed7a9e5dcc4 /chain
parent3ae0cf9898485a2ec35df7d23cd274e7dea5796d (diff)
new startHEADmaster
Now I tested and discussed with claude, and had a working version of this project. The rest is to port the claude version to my own writings. So this serves as the starting point before that attempt. In the new attempt the design is better, and a number of bugs were found and supposedly fixed, so let us see how this goes at the end.
Diffstat (limited to 'chain')
-rw-r--r--chain/src/atom/default.rs7
-rw-r--r--chain/src/default.rs27
-rw-r--r--chain/src/item/default/extract.rs2
-rw-r--r--chain/src/item/default/mod.rs16
-rw-r--r--chain/src/item/default/splone.rs41
-rw-r--r--chain/src/item/genins.rs12
-rw-r--r--chain/src/item/reduction.rs6
7 files changed, 62 insertions, 49 deletions
diff --git a/chain/src/atom/default.rs b/chain/src/atom/default.rs
index c6289f1..7e50868 100644
--- a/chain/src/atom/default.rs
+++ b/chain/src/atom/default.rs
@@ -545,7 +545,7 @@ impl DefaultAtom {
virtual_frags
.entry(VirtualNode::new(nt, t))
- .or_insert_with(Default::default)
+ .or_default()
.insert(rule, frag);
// Those left-linearly expanded arrows should
@@ -594,10 +594,7 @@ impl DefaultAtom {
for (_, target, _, pos) in set.iter() {
let trace = VirtualTrace::new(nt, t, *target);
- virtual_traces
- .entry(trace)
- .or_insert_with(Default::default)
- .insert(*pos);
+ virtual_traces.entry(trace).or_default().insert(*pos);
}
// add a virtual node
diff --git a/chain/src/default.rs b/chain/src/default.rs
index 042f84e..db42ef8 100644
--- a/chain/src/default.rs
+++ b/chain/src/default.rs
@@ -224,6 +224,9 @@ pub struct DefaultChain {
accepting_sources: Vec<PaVi>,
}
+// TODO: Implement saving the chain on disk, so that we do not have to
+// load the grammar every time.
+
impl DefaultChain {
/// Return the current node.
#[inline]
@@ -311,6 +314,7 @@ impl DefaultChain {
let mut file = std::fs::File::options()
.write(true)
.create(true)
+ .truncate(true)
.open(&filename)?;
use std::io::Write;
@@ -320,21 +324,25 @@ impl DefaultChain {
}
impl LabelGraph<Edge> for DefaultChain {
- type Iter<'a> = <DLGraph<Edge> as LabelGraph<Edge>>::Iter<'a>
+ type Iter<'a>
+ = <DLGraph<Edge> as LabelGraph<Edge>>::Iter<'a>
where
Self: 'a;
- type TupleIter<'a> = <DLGraph<Edge> as LabelGraph<Edge>>::TupleIter<'a>
+ type TupleIter<'a>
+ = <DLGraph<Edge> as LabelGraph<Edge>>::TupleIter<'a>
where
Self: 'a,
Edge: 'a;
- type LabelIter<'a> = <DLGraph<Edge> as LabelGraph<Edge>>::LabelIter<'a>
+ type LabelIter<'a>
+ = <DLGraph<Edge> as LabelGraph<Edge>>::LabelIter<'a>
where
Self: 'a,
Edge: 'a;
- type EdgeLabelIter<'a> = <DLGraph<Edge> as LabelGraph<Edge>>::EdgeLabelIter<'a>
+ type EdgeLabelIter<'a>
+ = <DLGraph<Edge> as LabelGraph<Edge>>::EdgeLabelIter<'a>
where
Self: 'a,
Edge: 'a;
@@ -554,7 +562,7 @@ impl Chain for DefaultChain {
/// to save some allocations.
fn generate_edges(
input: GeneratorInput<'_>,
- mut child_iter: impl Iterator<Item = usize> + ExactSizeIterator + Clone,
+ mut child_iter: impl ExactSizeIterator<Item = usize> + Clone,
atom_child_iter: impl Iterator<Item = usize> + Clone,
mut output: impl AsMut<Vec<(Roi, usize)>>,
) -> Result<bool, Error> {
@@ -693,6 +701,15 @@ impl Chain for DefaultChain {
let new_pavi = if !no_item {
// prepare forest fragment
+ // if ter == 0 {
+ // println!("{ter}, {t}, {atom_moved}, {atom_label}");
+ // println!(
+ // "hey: {:?}",
+ // self.atom.labels_of(0).unwrap().collect::<Vec<_>>()
+ // );
+ // panic!("test");
+ // }
+
let fragment =
generate_fragment([atom_moved.into(), Ter(ter).into()], pos)?;
diff --git a/chain/src/item/default/extract.rs b/chain/src/item/default/extract.rs
index c34f1da..2f9d6da 100644
--- a/chain/src/item/default/extract.rs
+++ b/chain/src/item/default/extract.rs
@@ -15,7 +15,7 @@
//!
//! 1. Every node in *S* is complete.
//! 2. For every node *n* in *S*, the subtree of *F* rooted at *n*
-//! consists entirely of complete nodes.
+//! consists entirely of complete nodes.
//!
//! # Uniqueness of the maximal completed sub-forest
//!
diff --git a/chain/src/item/default/mod.rs b/chain/src/item/default/mod.rs
index f532805..eef7def 100644
--- a/chain/src/item/default/mod.rs
+++ b/chain/src/item/default/mod.rs
@@ -535,7 +535,7 @@ impl<T: GraphLabel> Forest<T> for DefaultForest<ForestLabel<T>> {
builder.add_edge(f_node, f_child, node_label)?;
}
}
- } else if !children_match_p(&builder, f_node, fragment.borrow(), node)? {
+ } else if !children_match_p(&builder, f_node, fragment, node)? {
let cloned = self.clone_node(f_node, 0, false)?;
let mut builder = PLGBuilderMut::from_graph_mut(&mut self.graph);
@@ -594,8 +594,7 @@ impl<T: GraphLabel> Forest<T> for DefaultForest<ForestLabel<T>> {
for cloned_child in fragment.children_of(node)? {
let builder = PLGBuilderMut::from_graph_mut(&mut self.graph);
- if !children_match_p(&builder, f_node, fragment.borrow(), cloned_child)?
- {
+ if !children_match_p(&builder, f_node, fragment, cloned_child)? {
let cloned = self.clone_node(f_node, 0, false)?;
let mut builder = PLGBuilderMut::from_graph_mut(&mut self.graph);
@@ -652,7 +651,7 @@ impl<T: GraphLabel> Forest<T> for DefaultForest<ForestLabel<T>> {
continue 'node_loop;
}
- if children_match_p(&builder, f_node_clone, fragment.borrow(), node)? {
+ if children_match_p(&builder, f_node_clone, fragment, node)? {
continue 'node_loop;
}
}
@@ -720,12 +719,8 @@ impl<T: GraphLabel> Forest<T> for DefaultForest<ForestLabel<T>> {
continue 'node_loop;
}
- if children_match_p(
- &builder,
- f_node_clone,
- fragment.borrow(),
- cloned_child,
- )? {
+ if children_match_p(&builder, f_node_clone, fragment, cloned_child)?
+ {
continue 'cloned_loop;
}
}
@@ -1187,6 +1182,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
let mut file = std::fs::File::options()
.write(true)
.create(true)
+ .truncate(true)
.open(&filename)?;
use std::io::Write;
diff --git a/chain/src/item/default/splone.rs b/chain/src/item/default/splone.rs
index f540000..8a81bf6 100644
--- a/chain/src/item/default/splone.rs
+++ b/chain/src/item/default/splone.rs
@@ -41,26 +41,26 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
/// 1. Make sure it is labelled by a nonterminal.
///
/// 2. Check the status of the node. If it is packed, return an
- /// error.
+ /// error.
///
/// 3. Make a new label according to the given `end`. See the
- /// function
- /// [`create_new_label`][DefaultForest::<ForestLabel<GrammarLabel>>::create_new_label]
- /// for the process of making new labels.
+ /// function
+ /// [`create_new_label`][DefaultForest::<ForestLabel<GrammarLabel>>::create_new_label]
+ /// for the process of making new labels.
///
/// 4. If the new label is equal to the old label, and if
- /// `edge_index + 1` is equal to the degree of the node, then do
- /// nothing.
+ /// `edge_index + 1` is equal to the degree of the node, then
+ /// do nothing.
///
/// 5. If the new label is equal to the old label but
- /// `edge_index+1` is not equal to the degree of the node, then
- /// clone the node while preserving `edge_index + 1` many
- /// children.
+ /// `edge_index+1` is not equal to the degree of the node, then
+ /// clone the node while preserving `edge_index + 1` many
+ /// children.
///
/// 6. If the new label is not equal to the old label, then split
- /// the node. See the function
- /// [`split_node`][DefaultForest::<ForestLabel<GrammarLabel>>::split_node]
- /// for details.
+ /// the node. See the function
+ /// [`split_node`][DefaultForest::<ForestLabel<GrammarLabel>>::split_node]
+ /// for details.
///
/// # `completingp`
///
@@ -291,9 +291,10 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
/// 2. Preserve the old children as specified by `edge_index + 1`.
///
/// 3. If the new node is closed or if the new node is not cloned,
- /// then for each parent, clone the parent. Replace the original
- /// child of the parent, which pointed to the old node, by this
- /// new node. Other children are inherited from the old parent.
+ /// then for each parent, clone the parent. Replace the
+ /// original child of the parent, which pointed to the old
+ /// node, by this new node. Other children are inherited from
+ /// the old parent.
///
/// # Return
///
@@ -382,13 +383,13 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
///
/// 3. Pack the label.
///
- /// 4. Check if this label already exists. If so, clone the label and
- /// return it.
+ /// 4. Check if this label already exists. If so, clone the label
+ /// and return it.
///
/// 5. Else set the label to be a plain label.
///
/// 6. Check if this plain label already exists. If so, clone the
- /// existing label, and return the clone of the cloned label.
+ /// existing label, and return the clone of the cloned label.
///
/// 7. Else return the plain label.
///
@@ -590,7 +591,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
if degree >= edge_index + 2 {
let index_child = self.nth_child(clone, edge_index + 1)?;
- if self.is_prefix(index_child, fragment.borrow())? {
+ if self.is_prefix(index_child, fragment)? {
return Ok(None);
}
}
@@ -614,7 +615,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
if degree >= edge_index + 2 {
let index_child = self.nth_child(node, edge_index + 1)?;
- if self.is_prefix(index_child, fragment.borrow())? {
+ if self.is_prefix(index_child, fragment)? {
return Ok(None);
}
}
diff --git a/chain/src/item/genins.rs b/chain/src/item/genins.rs
index e3e79b6..7ac771c 100644
--- a/chain/src/item/genins.rs
+++ b/chain/src/item/genins.rs
@@ -180,7 +180,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
label: Edge,
ter: usize,
fragment: impl Borrow<DefaultForest<ForestLabel<GrammarLabel>>>,
- atom_child_iter: impl Iterator<Item = usize> + ExactSizeIterator + Clone,
+ atom_child_iter: impl ExactSizeIterator<Item = usize> + Clone,
atom: &DefaultAtom,
) -> Result<PaVi, Error> {
let root = if let Some(root) = self.root() {
@@ -304,7 +304,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
let is_empty_segment = pavi.is_empty();
if true_source.is_virtual() {
- self.close_pavi(atom.borrow(), true_source, pos)?;
+ self.close_pavi(atom, true_source, pos)?;
if to_print {
self.print_viz(&format!(
@@ -330,7 +330,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
let virtual_frag = atom.generate_virtual_frags(nt, t, Some(rule));
if let Some(frag) = virtual_frag {
- let mut frag = (*frag.get(0).unwrap()).clone();
+ let mut frag = (*frag.first().unwrap()).clone();
frag.set_pos(atom, node_label.label().start(), true)?;
@@ -377,7 +377,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
if let PaVi::Parent(node, edge, _) = pavi {
let nth_child = self.nth_child(node, edge)?;
- let reduced = self.reduction(nth_child, pos, ter, atom.borrow(), false)?;
+ let reduced = self.reduction(nth_child, pos, ter, atom, false)?;
// dbg!(reduced, nth_child, self.is_empty_node(reduced)?);
@@ -543,7 +543,9 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
self.print_viz("dbg forest.gv").unwrap();
- #[cfg(test)]
+ // atom.print_nfa("nfa.gv").unwrap();
+
+ // #[cfg(test)]
crate::item::default::print_labels(atom, self.borrow()).unwrap();
return Err(Error::CannotPlant);
diff --git a/chain/src/item/reduction.rs b/chain/src/item/reduction.rs
index 8f7471c..e1a3504 100644
--- a/chain/src/item/reduction.rs
+++ b/chain/src/item/reduction.rs
@@ -267,7 +267,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
stack.push(top);
stack.extend(
self.children_of(top)?
- .filter(|child| correct_ends.get(child).is_none()),
+ .filter(|child| !correct_ends.contains_key(child)),
);
} else if !inserted {
correct_ends.insert(top, Incorrect);
@@ -320,7 +320,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
stack.push(top);
stack.extend(
self.children_of(top)?
- .filter(|child| correct_ends.get(child).is_none()),
+ .filter(|child| !correct_ends.contains_key(child)),
);
} else if !inserted {
correct_ends.insert(top, Incorrect);
@@ -350,7 +350,7 @@ impl DefaultForest<ForestLabel<GrammarLabel>> {
panic!("a terminal node {top} has no ending position?");
}
Some(TNT::Non(nt)) => {
- self.close_pavi(atom.borrow(), PaVi::Virtual(nt, ter, top), pos)?;
+ self.close_pavi(atom, PaVi::Virtual(nt, ter, top), pos)?;
// dbg!(top, nt, ter, pos, self.degree(top)?, degree);