diff --git a/ext/Cargo.toml b/ext/Cargo.toml index 2a61ad92c..95aaeb665 100644 --- a/ext/Cargo.toml +++ b/ext/Cargo.toml @@ -23,26 +23,26 @@ query = { path = "crates/query" } sseq = { path = "crates/sseq", default-features = false } adler = "1" -anyhow = "1.0.0" -byteorder = "1.4.3" -dashmap = "4.0.0" -itertools = { version = "0.10.0", default-features = false, features = [ +anyhow = "1.0.98" +byteorder = "1.5.0" +dashmap = "6.1.0" +itertools = { version = "0.14.0", default-features = false, features = [ "use_alloc", ] } -rustc-hash = "1.1.0" -serde_json = { version = "1.0.0", features = ["preserve_order"] } -tracing = "0.1.40" -tracing-subscriber = { version = "0.3.18", features = ["env-filter"] } +rustc-hash = "2.1.1" +serde_json = { version = "1.0.141", features = ["preserve_order"] } +tracing = "0.1.41" +tracing-subscriber = { version = "0.3.19", features = ["env-filter"] } -zstd = { version = "0.9.0", optional = true } +zstd = { version = "0.13.3", optional = true } [target.'cfg(unix)'.dependencies] ctrlc = { version = "3", features = ["termination"] } [dev-dependencies] -expect-test = "1.1.0" -rstest = "0.17.0" -tempfile = "3.0.0" +expect-test = "1.5.1" +rstest = "0.25.0" +tempfile = "3.20.0" [lib] crate-type = ["cdylib", "rlib"] diff --git a/ext/crates/algebra/Cargo.toml b/ext/crates/algebra/Cargo.toml index f1bec82ad..ab8a8a923 100644 --- a/ext/crates/algebra/Cargo.toml +++ b/ext/crates/algebra/Cargo.toml @@ -16,21 +16,21 @@ fp = { path = "../fp", default-features = false } maybe-rayon = { path = "../maybe-rayon" } once = { path = "../once" } -anyhow = "1.0.0" -auto_impl = "1.0.0" -hashbrown = "0.14.0" -itertools = { version = "0.10.0", default-features = false, features = [ +anyhow = "1.0.98" +auto_impl = "1.3.0" +hashbrown = "0.15.4" +itertools = { version = "0.14.0", default-features = false, features = [ "use_alloc", ] } -nom = { version = "7.0.0", default-features = false, features = ["alloc"] } -rustc-hash = "1.1.0" -serde = { version = "1.0.0", features = ["derive"] } -serde_json = "1.0.0" +nom = { version = "8.0.0", default-features = false, features = ["alloc"] } +rustc-hash = "2.1.1" +serde = { version = "1.0.219", features = ["derive"] } +serde_json = "1.0.141" [dev-dependencies] bencher = "0.1.5" -expect-test = "1.1.0" -rstest = "0.17.0" +expect-test = "1.5.1" +rstest = "0.25.0" [features] default = ["odd-primes"] diff --git a/ext/crates/algebra/src/algebra/adem_algebra.rs b/ext/crates/algebra/src/algebra/adem_algebra.rs index bad7c8bcc..2fb979699 100644 --- a/ext/crates/algebra/src/algebra/adem_algebra.rs +++ b/ext/crates/algebra/src/algebra/adem_algebra.rs @@ -290,7 +290,7 @@ impl Algebra for AdemAlgebra { } fn basis_element_from_string(&self, mut elt: &str) -> Option<(i32, usize)> { - use nom::sequence::preceded; + use nom::{sequence::preceded, Parser}; use crate::steenrod_parser::{digits, p_or_sq}; @@ -310,7 +310,7 @@ impl Algebra for AdemAlgebra { if elt.is_empty() { break; } - let (rem, sqn) = preceded(p_or_sq, digits)(elt).ok()?; + let (rem, sqn) = preceded(p_or_sq, digits).parse(elt).ok()?; elt = rem; ps.push(sqn); diff --git a/ext/crates/algebra/src/algebra/milnor_algebra.rs b/ext/crates/algebra/src/algebra/milnor_algebra.rs index b36a77f06..f6565873a 100644 --- a/ext/crates/algebra/src/algebra/milnor_algebra.rs +++ b/ext/crates/algebra/src/algebra/milnor_algebra.rs @@ -587,7 +587,8 @@ impl Algebra for MilnorAlgebra { character::complete::char, combinator::{map, opt}, multi::{many0, separated_list1}, - sequence::{preceded, tuple}, + sequence::preceded, + Parser, }; use crate::steenrod_parser::{brackets, digits, p_or_sq}; @@ -598,29 +599,26 @@ impl Algebra for MilnorAlgebra { map(char('1'), |_| (0, 0)), map(char('b'), |_| (1, 0)), map(preceded(p_or_sq, digits), |i| self.beps_pn(0, i)), + map((tag("P^"), digits, char('_'), digits), |(_, s, _, t)| { + let entry = p.pow(s); + let degree = entry as i32 * self.q() * combinatorics::xi_degrees(p)[t]; + let mut elt = MilnorBasisElement { + degree, + q_part: 0, + p_part: vec![0; t], + }; + elt.p_part[t - 1] = entry as PPartEntry; + self.compute_basis(degree); + (degree, self.basis_element_to_index(&elt)) + }), map( - tuple((tag("P^"), digits, char('_'), digits)), - |(_, s, _, t)| { - let entry = p.pow(s); - let degree = entry as i32 * self.q() * combinatorics::xi_degrees(p)[t]; - let mut elt = MilnorBasisElement { - degree, - q_part: 0, - p_part: vec![0; t], - }; - elt.p_part[t - 1] = entry as PPartEntry; - self.compute_basis(degree); - (degree, self.basis_element_to_index(&elt)) - }, - ), - map( - tuple(( + ( many0(preceded(tag("Q_"), digits::)), opt(preceded( char('P'), brackets(separated_list1(char(','), digits)), )), - )), + ), |(q_list, p_list)| { let q_part = q_list.into_iter().fold(0, |acc, q| acc + (1 << q)); let mut elt = MilnorBasisElement { @@ -636,7 +634,7 @@ impl Algebra for MilnorAlgebra { ), )); - if let Ok(("", res)) = parser(elt) { + if let Ok(("", res)) = parser.parse(elt) { Some(res) } else { None diff --git a/ext/crates/algebra/src/module/finitely_presented_module.rs b/ext/crates/algebra/src/module/finitely_presented_module.rs index 214832e51..cdd1a669d 100644 --- a/ext/crates/algebra/src/module/finitely_presented_module.rs +++ b/ext/crates/algebra/src/module/finitely_presented_module.rs @@ -102,7 +102,7 @@ impl FinitelyPresentedModule { impl FinitelyPresentedModule { pub fn from_json(algebra: Arc, json: &Value) -> anyhow::Result { use anyhow::anyhow; - use nom::combinator::opt; + use nom::{combinator::opt, Parser}; use crate::steenrod_parser::digits; @@ -127,7 +127,7 @@ impl FinitelyPresentedModule { let mut v = FpVector::new(p, 0); for term in reln.as_str().unwrap().split(" + ") { - let (term, coef) = opt(digits)(term).unwrap(); + let (term, coef) = opt(digits).parse(term).unwrap(); let coef: u32 = coef.unwrap_or(1); let (op, gen) = term.rsplit_once(' ').unwrap_or(("1", term)); @@ -160,7 +160,7 @@ impl FinitelyPresentedModule { .collect::>>()?; relations.sort_unstable_by_key(|x| x.0); - for (degree, rels) in &relations.into_iter().group_by(|x| x.0) { + for (degree, rels) in &relations.into_iter().chunk_by(|x| x.0) { for deg in result.relations.max_computed_degree() + 1..degree { result.add_relations(deg, vec![]); } diff --git a/ext/crates/algebra/src/steenrod_parser.rs b/ext/crates/algebra/src/steenrod_parser.rs index b800479ef..f54e57849 100644 --- a/ext/crates/algebra/src/steenrod_parser.rs +++ b/ext/crates/algebra/src/steenrod_parser.rs @@ -9,7 +9,7 @@ use nom::{ bytes::complete::tag, character::complete::{alpha1, alphanumeric0, char, digit1 as digit, space0}, combinator::{map, map_res, opt, peek}, - error::{context, ParseError, VerboseError, VerboseErrorKind}, + error::{context, ErrorKind, ParseError}, multi::{many0, separated_list1}, sequence::{delimited, pair, preceded}, IResult as IResultBase, Parser, @@ -17,7 +17,7 @@ use nom::{ use crate::{adem_algebra::AdemBasisElement, algebra::milnor_algebra::PPart}; -type IResult = IResultBase>; +type IResult = IResultBase>; #[derive(Debug, Clone)] pub enum AlgebraBasisElt { @@ -38,30 +38,30 @@ pub enum AlgebraNode { pub type ModuleNode = Vec<(AlgebraNode, String)>; /// Pad both ends with whitespace -pub(crate) fn space<'a, O, E: ParseError<&'a str>, F: Parser<&'a str, O, E>>( +pub(crate) fn space<'a, O, E: ParseError<&'a str>, F: Parser<&'a str, Output = O, Error = E>>( f: F, -) -> impl FnMut(&'a str) -> IResultBase<&'a str, O, E> { +) -> impl Parser<&'a str, Output = O, Error = E> { delimited(space0, f, space0) } /// Surround with brackets -pub(crate) fn brackets<'a, O, E: ParseError<&'a str>, F: Parser<&'a str, O, E>>( +pub(crate) fn brackets<'a, O, E: ParseError<&'a str>, F: Parser<&'a str, Output = O, Error = E>>( f: F, -) -> impl FnMut(&'a str) -> IResultBase<&'a str, O, E> { +) -> impl Parser<&'a str, Output = O, Error = E> { delimited(char('('), f, char(')')) } pub(crate) fn digits(i: &str) -> IResult<&str, T> { - map_res(space(digit), FromStr::from_str)(i) + map_res(space(digit), FromStr::from_str).parse(i) } pub(crate) fn p_or_sq(i: &str) -> IResult<&str, &str> { - alt((tag("P"), tag("Sq")))(i) + alt((tag("P"), tag("Sq"))).parse(i) } fn fold_separated( - mut sep: impl Parser, - mut f: impl Parser, + mut sep: impl Parser, + mut f: impl Parser, mut acc: impl FnMut(O, O) -> O, ) -> impl FnMut(I) -> IResultBase { move |i: I| { @@ -141,7 +141,8 @@ fn algebra_generator(i: &str) -> IResult<&str, AlgebraBasisElt> { ), AlgebraBasisElt::AList, ), - ))(i) + )) + .parse(i) } fn scalar(i: &str) -> IResult<&str, i32> { @@ -149,7 +150,8 @@ fn scalar(i: &str) -> IResult<&str, i32> { digits, preceded(char('+'), digits), map(preceded(char('-'), digits), |x: i32| -x), - ))(i) + )) + .parse(i) } fn algebra_factor(i: &str) -> IResult<&str, AlgebraNode> { @@ -157,11 +159,12 @@ fn algebra_factor(i: &str) -> IResult<&str, AlgebraNode> { map(algebra_generator, AlgebraNode::BasisElt), map(scalar, AlgebraNode::Scalar), brackets(algebra_expr), - )))(i) + ))) + .parse(i) } fn algebra_term(i: &str) -> IResult<&str, AlgebraNode> { - let (i, sign) = opt(alt((char('+'), char('-'))))(i)?; + let (i, sign) = opt(alt((char('+'), char('-')))).parse(i)?; let (i, mut res) = fold_separated(char('*'), algebra_factor, |acc, val| { AlgebraNode::Product(Box::new(acc), Box::new(val)) @@ -182,16 +185,12 @@ fn algebra_expr(i: &str) -> IResult<&str, AlgebraNode> { } fn module_generator(i: &str) -> IResult<&str, String> { - let (rest, (a, more_str)) = pair(alpha1, alphanumeric0)(i)?; + let (rest, (a, more_str)) = pair(alpha1, alphanumeric0).parse(i)?; if a.starts_with("Sq") || a.starts_with('P') || a.starts_with('Q') { - return Err(nom::Err::Failure(VerboseError { - errors: vec![( - &i[0..a.len()], - VerboseErrorKind::Context( - "Module generators are not allowed to start with P, Q, or Sq", - ), - )], - })); + return Err(nom::Err::Failure(nom::error::Error::new( + &i[0..a.len()], + ErrorKind::Verify, + ))); } Ok((rest, a.to_string() + more_str)) } @@ -203,16 +202,17 @@ fn module_term(i: &str) -> IResult<&str, ModuleNode> { map(pair(space(algebra_term), char('*')), |(a, _)| a), map(char('-'), |_| Scalar(-1)), map(char('+'), |_| Scalar(1)), - )))(i) - .unwrap(); + ))) + .parse(i)?; - match space(module_generator)(i) { + match space(module_generator).parse(i) { Ok((i, gen)) => return Ok((i, vec![(prefix.unwrap_or(Scalar(1)), gen)])), Err(nom::Err::Error(_)) => (), Err(e) => return Err(e), } - let (i, expr) = context("Parsing bracketed expression", space(brackets(module_expr)))(i)?; + let (i, expr) = + context("Parsing bracketed expression", space(brackets(module_expr))).parse(i)?; Ok(( i, match prefix { @@ -236,10 +236,14 @@ fn module_expr(i: &str) -> IResult<&str, ModuleNode> { )(i) } -fn convert_error(i: &str) -> impl FnOnce(nom::Err>) -> anyhow::Error + '_ { +fn convert_error(i: &str) -> impl FnOnce(nom::Err>) -> anyhow::Error + '_ { move |err| { anyhow!(match err { - nom::Err::Error(e) | nom::Err::Failure(e) => nom::error::convert_error(i, e), + nom::Err::Error(e) | nom::Err::Failure(e) => format!( + "Parse error at position {}: {:?}", + i.len() - e.input.len(), + e.code + ), _ => format!("{err:#}"), }) } diff --git a/ext/crates/bivec/Cargo.toml b/ext/crates/bivec/Cargo.toml index 894c0bc9f..1f0f36b52 100644 --- a/ext/crates/bivec/Cargo.toml +++ b/ext/crates/bivec/Cargo.toml @@ -8,6 +8,6 @@ authors = [ edition = "2021" [dependencies] -serde = "1.0.0" +serde = "1.0.219" [features] diff --git a/ext/crates/chart/Cargo.toml b/ext/crates/chart/Cargo.toml index 6722ea71c..e092f66f3 100644 --- a/ext/crates/chart/Cargo.toml +++ b/ext/crates/chart/Cargo.toml @@ -6,4 +6,4 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dev-dependencies] -expect-test = "1.1.0" +expect-test = "1.5.1" diff --git a/ext/crates/fp/Cargo.toml b/ext/crates/fp/Cargo.toml index b2c796ac4..00351aaf4 100644 --- a/ext/crates/fp/Cargo.toml +++ b/ext/crates/fp/Cargo.toml @@ -7,14 +7,14 @@ edition = "2021" [dependencies] build_const = "0.2.2" -byteorder = "1.4.3" -cfg-if = "1.0.0" -dashmap = "5" -itertools = { version = "0.13.0" } +byteorder = "1.5.0" +cfg-if = "1.0.1" +dashmap = "6" +itertools = { version = "0.14.0" } paste = "1.0.15" -proptest = { version = "1.2", optional = true } -serde = "1.0.0" -serde_json = "1.0.0" +proptest = { version = "1.7", optional = true } +serde = "1.0.219" +serde_json = "1.0.141" maybe-rayon = { path = "../maybe-rayon" } @@ -22,11 +22,11 @@ maybe-rayon = { path = "../maybe-rayon" } # We use the proptest harness for our own tests fp = { path = ".", default-features = false, features = ["proptest"] } criterion = { version = "0.5", features = ["html_reports"] } -expect-test = "1.1.0" -pprof = { version = "0.13.0", features = ["criterion", "flamegraph"] } -proptest = "1.2" -rand = "0.8.4" -rstest = "0.17.0" +expect-test = "1.5.1" +pprof = { version = "0.15.0", features = ["criterion", "flamegraph"] } +proptest = "1.7" +rand = "0.9.2" +rstest = "0.26.0" [build-dependencies] build_const = "0.2.2" diff --git a/ext/crates/fp/benches/criterion.rs b/ext/crates/fp/benches/criterion.rs index bc3457629..344405680 100644 --- a/ext/crates/fp/benches/criterion.rs +++ b/ext/crates/fp/benches/criterion.rs @@ -32,8 +32,8 @@ fn row_reductions(c: &mut Criterion) { fn random_vector(p: ValidPrime, dimension: usize) -> Vec { let mut result = Vec::with_capacity(dimension); - let mut rng = rand::thread_rng(); - result.resize_with(dimension, || rng.gen::() % p); + let mut rng = rand::rng(); + result.resize_with(dimension, || rng.random::() % p); result } diff --git a/ext/crates/fp/src/vector/fp_wrapper/mod.rs b/ext/crates/fp/src/vector/fp_wrapper/mod.rs index 4e4169ea4..257067a7c 100644 --- a/ext/crates/fp/src/vector/fp_wrapper/mod.rs +++ b/ext/crates/fp/src/vector/fp_wrapper/mod.rs @@ -286,8 +286,8 @@ mod tests { use crate::{prime::ValidPrime, vector::FpVector}; fn random_vector(p: u32, dimension: usize) -> Vec { - let mut rng = rand::thread_rng(); - (0..dimension).map(|_| rng.gen_range(0..p)).collect() + let mut rng = rand::rng(); + (0..dimension).map(|_| rng.random_range(0..p)).collect() } #[rstest] diff --git a/ext/crates/maybe-rayon/Cargo.toml b/ext/crates/maybe-rayon/Cargo.toml index a49c3c0eb..392ec2922 100644 --- a/ext/crates/maybe-rayon/Cargo.toml +++ b/ext/crates/maybe-rayon/Cargo.toml @@ -6,7 +6,7 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rayon = { version = "1.8.0", optional = true } +rayon = { version = "1.10.0", optional = true } [features] default = [] diff --git a/ext/crates/once/Cargo.toml b/ext/crates/once/Cargo.toml index 1c9338106..8f5094c53 100644 --- a/ext/crates/once/Cargo.toml +++ b/ext/crates/once/Cargo.toml @@ -15,8 +15,8 @@ maybe-rayon = { path = "../maybe-rayon" } [dev-dependencies] criterion = "0.5" -pprof = { version = "0.14", features = ["criterion", "flamegraph"] } -proptest = "1.6.0" +pprof = { version = "0.15", features = ["criterion", "flamegraph"] } +proptest = "1.7.0" rand = "0.9" [features] diff --git a/ext/crates/once/benches/criterion/main.rs b/ext/crates/once/benches/criterion/main.rs index 772114a8a..fc6965d87 100644 --- a/ext/crates/once/benches/criterion/main.rs +++ b/ext/crates/once/benches/criterion/main.rs @@ -1,5 +1,7 @@ +use std::hint::black_box; + use criterion::{ - black_box, criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, + criterion_group, criterion_main, measurement::WallTime, BenchmarkGroup, Criterion, }; use once::{MultiIndexed, OnceBiVec, TwoEndedGrove}; use pprof::criterion::{Output, PProfProfiler}; diff --git a/ext/crates/sseq/Cargo.toml b/ext/crates/sseq/Cargo.toml index d08520b14..390aaabd4 100644 --- a/ext/crates/sseq/Cargo.toml +++ b/ext/crates/sseq/Cargo.toml @@ -13,13 +13,13 @@ fp = { path = "../fp/", default-features = false } maybe-rayon = { path = "../maybe-rayon" } once = { path = "../once/" } -serde = "1.0.0" -serde_json = "1.0.0" -tracing = "0.1.40" +serde = "1.0.219" +serde_json = "1.0.141" +tracing = "0.1.41" [dev-dependencies] -expect-test = "1.1.0" -rand = "0.8" +expect-test = "1.5.1" +rand = "0.9" [features] default = ["odd-primes"] diff --git a/flake.nix b/flake.nix index 8ff75161c..0b34e86eb 100644 --- a/flake.nix +++ b/flake.nix @@ -36,6 +36,7 @@ pkgs.hyperfine pkgs.binutils pkgs.cargo-binutils + pkgs.cargo-edit ]; }); };