1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//! Configuration for controlling evaluation behavior.
/// Upper bound on the total expression-tree size (nodes, counted without
/// sharing) of the operands and intermediate results of the symbolic
/// algorithms that can swell: [`Matrix::det`], [`Matrix::inv`],
/// [`Matrix::solve`], [`Matrix::diagonalize`], [`Matrix::jordan_form`],
/// [`Matrix::matrix_exp`] and [`Matrix::qr`], and (at a quarter of it) the
/// closed forms of `rsolve`.
///
/// When the budget is exceeded these return
/// [`SymplexError::ComputationFailed`](crate::base::errors::SymplexError::ComputationFailed)
/// whose reason starts with `"expression swell"` instead of running for an
/// unbounded time. The value is calibrated so that everything below it
/// finishes in well under a minute: a fully symbolic 7×7 determinant (5040
/// terms, ≈ 40 000 nodes) passes, an 8×8 one (≈ 360 000 nodes, many
/// minutes) is rejected.
///
/// [`Matrix::det`]: crate::matrix::Matrix::det
/// [`Matrix::inv`]: crate::matrix::Matrix::inv
/// [`Matrix::solve`]: crate::matrix::Matrix::solve
/// [`Matrix::diagonalize`]: crate::matrix::Matrix::diagonalize
/// [`Matrix::jordan_form`]: crate::matrix::Matrix::jordan_form
/// [`Matrix::matrix_exp`]: crate::matrix::Matrix::matrix_exp
/// [`Matrix::qr`]: crate::matrix::Matrix::qr
///
/// # Examples
///
/// ```
/// use symplex::prelude::*;
///
/// let ctx = Context::new();
/// // A tiny DAG whose *tree* is enormous: eₙ₊₁ = sin(eₙ) + cos(eₙ).
/// let mut e = ctx.symbol("x");
/// for _ in 0..16 {
/// e = &e.sin() + &e.cos();
/// }
/// let m = Matrix::new(vec![vec![e.clone(), ctx.int(1)], vec![ctx.int(1), e]]).unwrap();
/// let err = m.inv().unwrap_err();
/// assert!(err.to_string().contains("expression swell"), "{err}");
/// ```
pub const EXPRESSION_BUDGET: usize = 100_000;
/// Controls the bounds on automatic evaluation in constructors.
///
/// These guards prevent runaway computation from pathological inputs
/// like `7^(10^100)` which would allocate astronomical amounts of memory.