Assertion and Verbosity Macros
We describe here various macros provided by AbstractAlgebra.
Verbosity macros
There is a list of symbols called verbosity scopes which represent keywords used to trigger some particular macros within the codes. Each of these verbosity scopes is associated with a verbosity level, being set to $0$ by default. A verbosity macro is joined to a verbosity scope S
and a value k
(set to $1$ by default) such that, if the current verbosity level l
of S
is bigger than or equal to k
, then the macro triggers a given action.
AbstractAlgebra.add_verbosity_scope
— MethodAbstractAlgebra.add_verbosity_scope(s::Symbol) -> Nothing
Add the symbol s
to the list of (global) verbosity scopes.
Examples
julia> AbstractAlgebra.add_verbosity_scope(:MyScope)
AbstractAlgebra.set_verbosity_level
— MethodAbstractAlgebra.set_verbosity_level(s::Symbol, l::Int) -> Int
If s
represents a known verbosity scope, set the current verbosity level of s
to l
.
One can access the current verbosity level of s
by calling the function get_verbosity_level
.
If s
is not yet known as a verbosity scope, the function raises an ErrorException
showing the error message "Not a valid symbol". One can add s
to the list of verbosity scopes by calling the function add_verbosity_scope
.
Examples
julia> AbstractAlgebra.add_verbosity_scope(:MyScope)
julia> AbstractAlgebra.set_verbosity_level(:MyScope, 4)
4
julia> AbstractAlgebra.set_verbosity_level(:MyScope, 0)
0
AbstractAlgebra.get_verbosity_level
— MethodAbstractAlgebra.get_verbosity_level(s::Symbol) -> Int
If s
represents a known verbosity scope, return the current verbosity level of s
.
One can modify the current verbosity level of s
by calling the function set_verbosity_level
.
If s
is not yet known as a verbosity scope, the function raises an ErrorException
showing the error message "Not a valid symbol". One can add s
to the list of verbosity scopes by calling the function add_verbosity_scope
.
Examples
julia> AbstractAlgebra.add_verbosity_scope(:MyScope)
julia> AbstractAlgebra.get_verbosity_level(:MyScope)
0
julia> AbstractAlgebra.set_verbosity_level(:MyScope, 4)
4
julia> AbstractAlgebra.get_verbosity_level(:MyScope)
4
julia> AbstractAlgebra.set_verbosity_level(:MyScope, 0)
0
julia> AbstractAlgebra.get_verbosity_level(:MyScope)
0
Printings
AbstractAlgebra.@vprintln
— Macro@vprintln(S::Symbol, k::Int, msg::String)
@vprintln S k msg
@vprintln(S::Symbol, msg::String)
@vprintln S msg
This macro can be used to control printings inside the code.
The macro @vprintln
takes two or three arguments: a symbol S
specifying a verbosity scope, an optional integer k
and a string msg
. If k
is not specified, it is set by default to $1$.
To each verbosity scope S
is associated a verbosity level l
which is cached. If the verbosity level $l$ of S
is bigger than or equal to $k$, the macro @vprintln
triggers the printing of the associated string msg
followed by a newline.
One can add a new verbosity scope by calling the function add_verbosity_scope
.
When starting a new instance, all the verbosity levels are set to $0$. One can adjust the verbosity level of a verbosity scope by calling the function set_verbosity_level
.
One can access the current verbosity level of a verbosity scope by calling the function get_verbosity_level
.
Examples
We will set up different verbosity scopes with different verbosity levels in a custom function to show how to use this macro.
julia> AbstractAlgebra.add_verbosity_scope(:Test1);
julia> AbstractAlgebra.add_verbosity_scope(:Test2);
julia> AbstractAlgebra.add_verbosity_scope(:Test3);
julia> AbstractAlgebra.set_verbosity_level(:Test1, 1);
julia> AbstractAlgebra.set_verbosity_level(:Test2, 3);
julia> function vprint_example()
@vprintln :Test1 "Triggered"
@vprintln :Test2 2 "Triggered"
@vprintln :Test3 "Not triggered"
@vprintln :Test2 4 "Not triggered"
end
vprint_example (generic function with 1 method)
julia> vprint_example()
Triggered
Triggered
If one does not setup in advance a verbosity scope, the macro will raise an ExceptionError
showing the error message "Not a valid symbol".
AbstractAlgebra.@vprint
— Macro@vprint(S::Symbol, k::Int, msg::String)
@vprint S k msg
@vprint(S::Symbol, msg::String)
@vprint S msg
The same as @vprintln
, but without the final newline.
Actions
AbstractAlgebra.@v_do
— Macro@v_do(S::Symbol, k::Int, act::Expr)
@v_do S k act
@v_do(S::Symbol, act::Expr)
@v_do S act
This macro can be used to control actions inside the code.
The macro @v_do
takes two or three arguments: a symbol S
specifying a verbosity scope, an optional integer k
and an action act
. If k
is not specified, it is set by default to $1$.
To each verbosity scope S
is associated a verbosity level l
. If the verbosity level $l$ of S
is bigger than or equal to $k$, the macro @v_do
triggers the action act
.
One can add a new verbosity scope by calling the function add_verbosity_scope
.
When starting a new instance, all the verbosity levels are set to $0$. One can adjust the verbosity level of a verbosity scope by calling the function set_verbosity_level
.
One can access the current verbosity level of a verbosity scope by calling the function get_verbosity_level
.
Examples
We will set up different verbosity scopes with different verbosity levels in a custom function to show how to use this macro.
julia> AbstractAlgebra.add_verbosity_scope(:Test1);
julia> AbstractAlgebra.add_verbosity_scope(:Test2);
julia> AbstractAlgebra.add_verbosity_scope(:Test3);
julia> AbstractAlgebra.set_verbosity_level(:Test1, 1);
julia> AbstractAlgebra.set_verbosity_level(:Test2, 3);
julia> function v_do_example(a::Int, b::Int, c::Int, d::Int)
@v_do :Test1 a = 2*a
@v_do :Test2 2 b = 3*b
@v_do :Test3 c = 4*c
@v_do :Test2 4 d = 5*d
return (a, b, c, d)
end
v_do_example (generic function with 1 method)
julia> v_do_example(1,1,1,1)
(2, 3, 1, 1)
If one does not setup in advance a verbosity scope, the macro will raise an ExceptionError
showing the error message "Not a valid symbol".
Assertion macros
There is a list of symbols called assertion scopes which represent keywords used to trigger some particular macros within the codes. Each of these assertion scopes is associated with an assertion level, being set to $0$ by default. An assertion macro is joined to an assertion scope S
and a value k
(set to $1$ by default) such that, if the current assertion level l
of S
is bigger than or equal to k
, then the macro triggers an action on the given assertion
AbstractAlgebra.add_assertion_scope
— MethodAbstractAlgebra.add_assertion_scope(s::Symbol) -> Nothing
Add the symbol s
to the list of (global) assertion scopes.
Examples
julia> AbstractAlgebra.add_assertion_scope(:MyScope)
AbstractAlgebra.set_assertion_level
— MethodAbstractAlgebra.set_assertion_level(s::Symbol, l::Int) -> Int
If s
represents a known assertion scope, set the current assertion level of s
to l
.
One can access the current assertion level of s
by calling the function get_assertion_level
.
If s
is not yet known as an assertion scope, the function raises an ErrorException
showing the error message "Not a valid symbol". One can add s
to the list of assertion scopes by calling the function add_assertion_scope
.
Examples
julia> AbstractAlgebra.add_assertion_scope(:MyScope)
julia> AbstractAlgebra.set_assertion_level(:MyScope, 4)
4
julia> AbstractAlgebra.set_assertion_level(:MyScope, 0)
0
AbstractAlgebra.get_assertion_level
— MethodAbstractAlgebra.get_assertion_level(s::Symbol) -> Int
If s
represents a symbol of a known assertion scope, return the current assertion level of s
.
One can modify the current assertion level of s
by calling the function set_assertion_level
.
If s
is not yet known as an assertion scope, the function raises an ErrorException
showing the error message "Not a valid symbol". One can add s
to the list of assertion scopes by calling the function add_assertion_scope
.
Examples
julia> AbstractAlgebra.add_assertion_scope(:MyScope)
julia> AbstractAlgebra.get_assertion_level(:MyScope)
0
julia> AbstractAlgebra.set_assertion_level(:MyScope, 1)
1
julia> AbstractAlgebra.get_assertion_level(:MyScope)
1
julia> AbstractAlgebra.set_assertion_level(:MyScope, 0)
0
julia> AbstractAlgebra.get_assertion_level(:MyScope)
0
Check
AbstractAlgebra.@hassert
— Macro@hassert(S::Symbol, k::Int, assert::Expr)
@hassert S k assert
@hassert(S::Symbol, assert::Expr)
@hassert S assert
This macro can be used to control assertion checks inside the code.
The macro @hassert
takes two or three arguments: a symbol S
specifying an assertion scope, an optional integer k
and an assertion assert
. If k
is not specified, it is set by default to $1$.
To each assertion scope S
is associated an assertion level l
which is cached. If the assertion level $l$ of S
is bigger than or equal to $k$, the macro @hassert
triggers the check of the assertion assert
. If assert
is wrong, an AssertionError
is thrown.
One can add a new assertion scope by calling the function add_assertion_scope
.
When starting a new instance, all the assertion levels are set to $0$. One can adjust the assertion level of an assertion scope by calling the function set_assertion_level
.
One can access the current assertion level of an assertion scope by calling the function get_assertion_level
.
Examples
We will set up different assertion scopes with different assertion levels in a custom function to show how to use this macro.
julia> AbstractAlgebra.add_assertion_scope(:MyScope)
julia> AbstractAlgebra.get_assertion_level(:MyScope)
0
julia> function hassert_test(x::Int)
@hassert :MyScope 700 mod(x, 3) == 0
return div(x, 3)
end
hassert_test (generic function with 1 method)
julia> hassert_test(2)
0
julia> AbstractAlgebra.set_assertion_level(:MyScope, 701);
julia> try hassert_test(2)
catch e e
end
AssertionError("\$(Expr(:escape, :(mod(x, 3) == 0)))")
julia> hassert_test(3)
1
julia> AbstractAlgebra.set_assertion_level(:MyScope, 0)
0
If one does not setup in advance an assertion scope, the macro will raise an ExceptionError
showing the error message "Not a valid symbol".
Miscellaneous
AbstractAlgebra.@req
— Macro@req(assert, msg)
@req assert msg
Check whether the assertion assert
is true. If not, throw an ArgumentError
with error message msg
.
The macro @req
takes two arguments: the first one is an assertion assert
(an expression which returns a boolean) and a string msg
corresponding to the desired error message to be returned whenever assert
is false.
If the number of arguments is not 2, an AssertionError
is raised.
Examples
julia> function req_test(x::Int)
@req iseven(x) "x must be even"
return div(x,2)
end
req_test (generic function with 1 method)
julia> try req_test(3)
catch e e
end
ArgumentError("x must be even")
julia> try req_test(2)
catch e e
end
1