Skip to content

Commit 41a43fd

Browse files
docs: add documentation for assertions functionality
1 parent f9b8f52 commit 41a43fd

File tree

3 files changed

+43
-1
lines changed

3 files changed

+43
-1
lines changed

docs/src/basics/Debugging.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,23 @@ dsol = solve(dprob, Tsit5());
3535
Now we see that it crashed because `u1` decreased so much that it became negative and outside the domain of the `` function.
3636
We could have figured that out ourselves, but it is not always so obvious for more complex models.
3737

38+
Suppose we also want to validate that `u1 + u2 >= 2.0`. We can do this via the assertions functionality.
39+
40+
```@example debug
41+
@mtkbuild sys = ODESystem(eqs, t; defaults, assertions = [(u1 + u2 >= 2.0) => "Oh no!"])
42+
```
43+
44+
The assertions must be an iterable of pairs, where the first element is the symbolic condition and
45+
the second is the message to be logged when the condition fails.
46+
47+
```@repl debug
48+
dsys = debug_system(sys; functions = []);
49+
dprob = ODEProblem(dsys, [], (0.0, 10.0));
50+
dsol = solve(dprob, Tsit5());
51+
```
52+
53+
Note the messages containing the failed assertion and corresponding message.
54+
3855
```@docs
3956
debug_system
4057
```

src/debugging.jl

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,13 @@ function debug_sub(ex, funcs; kw...)
4343
maketerm(typeof(ex), f, args, metadata(ex))
4444
end
4545

46+
"""
47+
$(TYPEDSIGNATURES)
48+
49+
A function which takes a condition `expr` and returns `NaN` if it is false,
50+
and zero if it is true. In case the condition is false and `log == true`,
51+
`message` will be logged as an `@error`.
52+
"""
4653
function _debug_assertion(expr::Bool, message::String, log::Bool)
4754
expr && return 0.0
4855
log && @error message
@@ -51,9 +58,19 @@ end
5158

5259
@register_symbolic _debug_assertion(expr::Bool, message::String, log::Bool)
5360

61+
"""
62+
Boolean parameter added to models returned from `debug_system` to control logging of
63+
assertions.
64+
"""
5465
const ASSERTION_LOG_VARIABLE = only(@parameters __log_assertions_ₘₜₖ::Bool = false)
5566

56-
function get_assertions_expr(assertions::Dict{BasicSymbolic, String})
67+
"""
68+
$(TYPEDSIGNATURES)
69+
70+
Get a symbolic expression as per the requirement of `debug_system` for all the assertions
71+
in `assertions`. `is_split` denotes whether the corresponding system is a split system.
72+
"""
73+
function get_assertions_expr(assertions::Dict{BasicSymbolic, String}, is_split::Bool)
5774
term = 0
5875
for (k, v) in assertions
5976
term += _debug_assertion(k, "Assertion $k failed:\n$v", ASSERTION_LOG_VARIABLE)

src/systems/abstractsystem.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2302,6 +2302,14 @@ ERROR: Function /(1, sin(P(t))) output non-finite value Inf with input
23022302
1 => 1
23032303
sin(P(t)) => 0.0
23042304
```
2305+
2306+
Additionally, all assertions in the system are validated in the equations. If any of
2307+
the conditions are false, the right hand side of at least one of the equations of
2308+
the system will evaluate to `NaN`. A new parameter is also added to the system which
2309+
controls whether the message associated with each assertion will be logged when the
2310+
assertion fails. This parameter defaults to `true` and can be toggled by
2311+
symbolic indexing with `ModelingToolkit.ASSERTION_LOG_VARIABLE`. For example,
2312+
`prob.ps[ModelingToolkit.ASSERTION_LOG_VARIABLE] = false` will disable logging.
23052313
"""
23062314
function debug_system(
23072315
sys::AbstractSystem; functions = [log, sqrt, (^), /, inv, asin, acos], kw...)

0 commit comments

Comments
 (0)