Skip to content

Commit 5478e86

Browse files
Merge pull request #775 from ChrisRackauckas-Claude/add-missing-docstrings
Add comprehensive docstrings for all public API functions
2 parents 7e4daa2 + 2963875 commit 5478e86

File tree

5 files changed

+495
-4
lines changed

5 files changed

+495
-4
lines changed

docs/src/api.md

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,117 @@
11
# API Reference
22

33
## Symbols and Terms
4+
5+
### Creating Symbols and Terms
46
```@docs
57
SymbolicUtils.@syms
8+
SymbolicUtils.term
69
SymbolicUtils.Sym
10+
```
11+
12+
### Inspecting Terms
13+
```@docs
714
SymbolicUtils.issym
815
SymbolicUtils.symtype
16+
SymbolicUtils.iscall
17+
SymbolicUtils.operation
18+
SymbolicUtils.arguments
19+
SymbolicUtils.sorted_arguments
20+
SymbolicUtils.showraw
21+
```
22+
23+
### Term Types
24+
```@docs
925
SymbolicUtils.Term
1026
SymbolicUtils.Add
1127
SymbolicUtils.Mul
1228
SymbolicUtils.Pow
29+
```
30+
31+
### Metadata
32+
```@docs
33+
SymbolicUtils.hasmetadata
34+
SymbolicUtils.getmetadata
35+
SymbolicUtils.setmetadata
36+
```
37+
38+
### Type Promotion
39+
```@docs
1340
SymbolicUtils.promote_symtype
1441
```
1542

16-
## Rewriters
43+
## Rewriting System
1744

45+
### Rule Creation
1846
```@docs
1947
@rule
48+
@acrule
49+
```
50+
51+
### Rewriters
52+
```@docs
2053
SymbolicUtils.Rewriters
54+
SymbolicUtils.Rewriters.Empty
55+
SymbolicUtils.Rewriters.IfElse
56+
SymbolicUtils.Rewriters.If
57+
SymbolicUtils.Rewriters.Chain
58+
SymbolicUtils.Rewriters.RestartedChain
59+
SymbolicUtils.Rewriters.Fixpoint
60+
SymbolicUtils.Rewriters.FixpointNoCycle
61+
SymbolicUtils.Rewriters.Postwalk
62+
SymbolicUtils.Rewriters.Prewalk
63+
SymbolicUtils.Rewriters.PassThrough
2164
```
2265

23-
## Simplify
66+
## Simplification and Transformation
2467

2568
```@docs
2669
SymbolicUtils.simplify
2770
SymbolicUtils.expand
2871
SymbolicUtils.substitute
2972
```
3073

74+
## Polynomial Forms
75+
76+
```@docs
77+
SymbolicUtils.PolyForm
78+
SymbolicUtils.simplify_fractions
79+
SymbolicUtils.quick_cancel
80+
SymbolicUtils.flatten_fractions
81+
```
82+
83+
## Code Generation
84+
85+
### Core Functions
86+
```@docs
87+
SymbolicUtils.toexpr
88+
SymbolicUtils.cse
89+
```
90+
91+
### Code Generation Types
92+
```@docs
93+
SymbolicUtils.Assignment
94+
SymbolicUtils.Let
95+
SymbolicUtils.Func
96+
SymbolicUtils.DestructuredArgs
97+
SymbolicUtils.LiteralExpr
98+
SymbolicUtils.ForLoop
99+
```
100+
101+
### Array Operations
102+
```@docs
103+
SymbolicUtils.SetArray
104+
SymbolicUtils.MakeArray
105+
SymbolicUtils.MakeSparseArray
106+
SymbolicUtils.MakeTuple
107+
```
108+
109+
### Parallelism
110+
```@docs
111+
SymbolicUtils.SpawnFetch
112+
SymbolicUtils.Multithreaded
113+
```
114+
31115
## Utilities
32116

33117
```@docs

src/code.jl

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,21 @@ function toexpr(a::MakeTuple, st)
666666
:(($(toexpr.(a.elems, (st,))...),))
667667
end
668668

669+
"""
670+
Multithreaded
671+
672+
A parallelism type for `SpawnFetch` that uses Julia's threading system.
673+
674+
When used with `SpawnFetch{Multithreaded}`, expressions are executed
675+
in parallel using `Threads.@spawn`.
676+
677+
# Examples
678+
```julia
679+
julia> SpawnFetch{Multithreaded}([func1, func2], combine_func)
680+
```
681+
682+
See also: [`SpawnFetch`](@ref)
683+
"""
669684
struct Multithreaded end
670685
"""
671686
SpawnFetch{ParallelType}(funcs [, args], reduce)
@@ -834,8 +849,22 @@ end
834849
"""
835850
$(TYPEDSIGNATURES)
836851
837-
Perform Common Subexpression Elimination on the given expression `expr`. Return an
838-
equivalent `expr` with optimized computation.
852+
Perform common subexpression elimination on an expression.
853+
854+
This optimization identifies repeated subexpressions and replaces them with
855+
variables to avoid redundant computation.
856+
857+
# Arguments
858+
- `expr`: The expression to optimize
859+
860+
# Returns
861+
An optimized expression with common subexpressions eliminated
862+
863+
# Examples
864+
```julia
865+
julia> expr = :(sin(x) + sin(x) * cos(y))
866+
julia> cse(expr) # sin(x) is computed only once
867+
```
839868
"""
840869
function cse(expr)
841870
state = CSEState()

src/rewriters.jl

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,45 @@ export Empty, IfElse, If, Chain, RestartedChain, Fixpoint, Postwalk, Prewalk, Pa
4040
const repr_cache = IdDict()
4141
cached_repr(x) = Base.get!(()->repr(x), repr_cache, x)
4242

43+
"""
44+
Empty()
45+
46+
A rewriter that always returns `nothing`, indicating no rewrite occurred.
47+
48+
This is useful as a placeholder or for conditional rewriting patterns.
49+
50+
# Examples
51+
```julia
52+
julia> Empty()(x)
53+
nothing
54+
```
55+
"""
4356
struct Empty end
4457

4558
(rw::Empty)(x) = nothing
4659

4760
instrument(x, f) = f(x)
4861
instrument(x::Empty, f) = x
4962

63+
"""
64+
IfElse(cond, yes, no)
65+
66+
A conditional rewriter that applies `yes` if `cond(x)` is true, otherwise applies `no`.
67+
68+
# Arguments
69+
- `cond`: A function that returns true or false for the input
70+
- `yes`: The rewriter to apply if the condition is true
71+
- `no`: The rewriter to apply if the condition is false
72+
73+
# Examples
74+
```julia
75+
julia> r = IfElse(x -> x > 0, x -> -x, x -> x)
76+
julia> r(5) # Returns -5
77+
julia> r(-3) # Returns -3
78+
```
79+
80+
See also: [`If`](@ref)
81+
"""
5082
struct IfElse{F, A, B}
5183
cond::F
5284
yes::A
@@ -59,8 +91,46 @@ function (rw::IfElse)(x)
5991
rw.cond(x) ? rw.yes(x) : rw.no(x)
6092
end
6193

94+
"""
95+
If(cond, yes)
96+
97+
A conditional rewriter that applies `yes` if `cond(x)` is true, otherwise returns the input unchanged.
98+
99+
This is equivalent to `IfElse(cond, yes, Empty())`.
100+
101+
# Arguments
102+
- `cond`: A function that returns true or false for the input
103+
- `yes`: The rewriter to apply if the condition is true
104+
105+
# Examples
106+
```julia
107+
julia> r = If(x -> x > 0, x -> -x)
108+
julia> r(5) # Returns -5
109+
julia> r(-3) # Returns -3 (unchanged)
110+
```
111+
"""
62112
If(f, x) = IfElse(f, x, Empty())
63113

114+
"""
115+
Chain(rws; stop_on_match=false)
116+
117+
Apply a sequence of rewriters to an expression, chaining the results.
118+
119+
Each rewriter in the chain receives the result of the previous rewriter.
120+
If a rewriter returns `nothing`, the input is passed unchanged to the next rewriter.
121+
122+
# Arguments
123+
- `rws`: A collection of rewriters to apply in sequence
124+
- `stop_on_match`: If true, stop at the first rewriter that produces a change
125+
126+
# Examples
127+
```julia
128+
julia> r1 = @rule sin(~x)^2 + cos(~x)^2 => 1
129+
julia> r2 = @rule sin(2*(~x)) => 2*sin(~x)*cos(~x)
130+
julia> chain = Chain([r1, r2])
131+
julia> chain(sin(x)^2 + cos(x)^2) # Returns 1
132+
```
133+
"""
64134
struct Chain
65135
rws
66136
stop_on_match::Bool
@@ -83,6 +153,25 @@ function (rw::Chain)(x)
83153
end
84154
instrument(c::Chain, f) = Chain(map(x->instrument(x,f), c.rws))
85155

156+
"""
157+
RestartedChain(rws)
158+
159+
Apply rewriters in sequence, restarting the chain when any rewriter produces a change.
160+
161+
When any rewriter in the chain produces a non-nothing result, the entire chain
162+
is restarted with that result as the new input.
163+
164+
# Arguments
165+
- `rws`: A collection of rewriters to apply
166+
167+
# Examples
168+
```julia
169+
julia> r1 = @rule ~x + ~x => 2 * ~x
170+
julia> r2 = @rule 2 * ~x => ~x * 2
171+
julia> chain = RestartedChain([r1, r2])
172+
julia> chain(x + x) # Applies r1, then restarts and applies r2
173+
```
174+
"""
86175
struct RestartedChain{Cs}
87176
rws::Cs
88177
end
@@ -114,6 +203,26 @@ end
114203
end
115204

116205

206+
"""
207+
Fixpoint(rw)
208+
209+
Apply a rewriter repeatedly until a fixed point is reached.
210+
211+
The rewriter is applied repeatedly until the output equals the input
212+
(either by identity or by `isequal`), indicating a fixed point has been reached.
213+
214+
# Arguments
215+
- `rw`: The rewriter to apply repeatedly
216+
217+
# Examples
218+
```julia
219+
julia> r = @rule ~x + ~x => 2 * ~x
220+
julia> fp = Fixpoint(r)
221+
julia> fp(x + x + x + x) # Keeps applying until no more changes
222+
```
223+
224+
See also: [`FixpointNoCycle`](@ref)
225+
"""
117226
struct Fixpoint{C}
118227
rw::C
119228
end
@@ -180,14 +289,80 @@ end
180289
using .Threads
181290

182291

292+
"""
293+
Postwalk(rw; threaded=false, thread_cutoff=100, maketerm=maketerm)
294+
295+
Apply a rewriter to a symbolic expression tree in post-order (bottom-up).
296+
297+
Post-order traversal visits child nodes before their parents, allowing for
298+
simplification of subexpressions before the containing expression.
299+
300+
# Arguments
301+
- `rw`: The rewriter to apply at each node
302+
- `threaded`: If true, use multi-threading for large expressions
303+
- `thread_cutoff`: Minimum node count to trigger threading
304+
- `maketerm`: Function to construct terms (defaults to `maketerm`)
305+
306+
# Examples
307+
```julia
308+
julia> r = @rule ~x + ~x => 2 * ~x
309+
julia> pw = Postwalk(r)
310+
julia> pw((x + x) * (y + y)) # Simplifies both additions
311+
2x * 2y
312+
```
313+
314+
See also: [`Prewalk`](@ref)
315+
"""
183316
function Postwalk(rw; threaded::Bool=false, thread_cutoff=100, maketerm=maketerm)
184317
Walk{:post, typeof(rw), typeof(maketerm), threaded}(rw, thread_cutoff, maketerm)
185318
end
186319

320+
"""
321+
Prewalk(rw; threaded=false, thread_cutoff=100, maketerm=maketerm)
322+
323+
Apply a rewriter to a symbolic expression tree in pre-order (top-down).
324+
325+
Pre-order traversal visits parent nodes before their children, allowing for
326+
transformation of the overall structure before processing subexpressions.
327+
328+
# Arguments
329+
- `rw`: The rewriter to apply at each node
330+
- `threaded`: If true, use multi-threading for large expressions
331+
- `thread_cutoff`: Minimum node count to trigger threading
332+
- `maketerm`: Function to construct terms (defaults to `maketerm`)
333+
334+
# Examples
335+
```julia
336+
julia> r = @rule sin(~x) => cos(~x)
337+
julia> pw = Prewalk(r)
338+
julia> pw(sin(sin(x))) # Transforms outer sin first
339+
cos(cos(x))
340+
```
341+
342+
See also: [`Postwalk`](@ref)
343+
"""
187344
function Prewalk(rw; threaded::Bool=false, thread_cutoff=100, maketerm=maketerm)
188345
Walk{:pre, typeof(rw), typeof(maketerm), threaded}(rw, thread_cutoff, maketerm)
189346
end
190347

348+
"""
349+
PassThrough(rw)
350+
351+
A rewriter that returns the input unchanged if the wrapped rewriter returns `nothing`.
352+
353+
This is useful for making rewriters that preserve the input when no rule applies.
354+
355+
# Arguments
356+
- `rw`: The rewriter to wrap
357+
358+
# Examples
359+
```julia
360+
julia> r = @rule sin(~x) => cos(~x)
361+
julia> pt = PassThrough(r)
362+
julia> pt(sin(x)) # Returns cos(x)
363+
julia> pt(tan(x)) # Returns tan(x) unchanged
364+
```
365+
"""
191366
struct PassThrough{C}
192367
rw::C
193368
end

0 commit comments

Comments
 (0)