Deserialize a `System ` from [`to_bytes`] output, requiring that every byte is consumed.
(bytes: &[u8])
| 353 | let mut lookups = Vec::with_capacity(lookup_count); |
| 354 | for _ in 0..lookup_count { |
| 355 | let multiplicity = seg.node_id()?; |
| 356 | let arg_count = seg.u16()? as usize; |
| 357 | let mut args = Vec::with_capacity(arg_count.min(1 << 16)); |
| 358 | for _ in 0..arg_count { |
| 359 | args.push(seg.node_id()?); |
| 360 | } |
| 361 | lookups.push(Lookup { multiplicity, args }); |
| 362 | } |
| 363 | |
| 364 | let degrees = recompute_degrees(&nodes); |
| 365 | // The graph's own max degree covers only the user roots (the serialized |
| 366 | // `max_constraint_degree` is the combined user + analytic-logUp value). |
| 367 | let user_max_degree = zeros |
| 368 | .iter() |
| 369 | .map(|z| degrees[usize::try_from(z.0).expect("node id")]) |
| 370 | .max() |
| 371 | .unwrap_or(0); |
| 372 | // The lookup prefix is exactly the nodes interned while compiling the |
| 373 | // lookup expressions, all of which are reachable from (and bounded by) |
| 374 | // the lookup roots — children always precede parents. |
| 375 | let lookup_prefix_len = lookups |
| 376 | .iter() |
| 377 | .flat_map(|l| std::iter::once(l.multiplicity).chain(l.args.iter().copied())) |
| 378 | .map(|id| id.0 as usize + 1) |