API
IntervalArithmetic.IntervalArithmetic — Module
IntervalArithmeticLibrary for validated numerics using interval arithmetic. It provides tools for performing numerical calculations with guaranteed bounds by representing values as intervals: computed results enclose the true value. It is well-suited for computer-assisted proofs, and any context requiring certified numerics.
Learn more: https://github.com/JuliaIntervals/IntervalArithmetic.jl.
Configuration options
The behavior and performance of the library can be customized through the following parameters. All defaults can be modified using IntervalArithmetic.configure.
Bound Type: The default numerical type used for interval endpoints. The default is
Float64, but any subtype ofIntervalArithmetic.NumTypesmay be used to adjust precision, or specific numerical requirements.Flavor: The interval interpretation according to the IEEE Standard 1788-2015. The default is the set-based flavor, which excludes infinity from intervals. Learn more:
IntervalArithmetic.Flavor.Interval Rounding: The rounding behavior for interval arithmetic operations. By default, the library employs correct rounding to ensure that bounds are computed as tightly as possible. Learn more:
IntervalArithmetic.IntervalRounding.Power mode: The performance setting for computing powers. The default is an efficient algorithm prioritizing performance over precision. Learn more:
IntervalArithmetic.PowerMode.Matrix Multiplication mode: The performance setting for computing matrix multiplications. The default is an efficient algorithm prioritizing performance over precision. Learn more:
IntervalArithmetic.MatMulMode.
Display settings
The display of intervals is controlled by setdisplay. By default, the intervals are shown using the standard mathematical notation $[a, b]$, along with decorations and up to 6 significant digits.
IntervalArithmetic.BareInterval — Type
BareInterval{T<:NumTypes}Interval type for guaranteed computation with interval arithmetic according to the IEEE Standard 1788-2015. Unlike Interval, this bare interval does not have decorations, is not a subtype of Real and errors on operations mixing BareInterval and Number.
Fields:
lo :: Thi :: T
Constructor compliant with the IEEE Standard 1788-2015: bareinterval.
See also: Interval.
IntervalArithmetic.Constant — Type
Constant(value)A constant function compatible with interval arithmetic.
Return an interval containing only the value for an interval input, and the value directly otherwise.
julia> using IntervalArithmetic
julia> setdisplay(:full);
julia> c = Constant(1.2)
Constant{Float64}(1.2)
julia> c(22.2)
1.2
julia> c(interval(0, 1.3))
Interval{Float64}(1.2, 1.2, com, true)Note that this is not equivalent to Returns(value) from base, which always outputs value, even for an interval input. This can shortcircuit the propagation of intervals in the computation and lose the associated guarantee of correctness.
IntervalArithmetic.Domain — Type
Domain{LeftBound, RightBound}(lo, hi)The domain of a function.
LeftBound and RightBound must be symbols and are either :closed or :open determining if the corresponding endpoint is (respectively) included or not in the domain.
If hi > lo, the domain is considered to be empty.
IntervalArithmetic.ExactReal — Type
ExactReal{T<:Real} <: RealReal numbers with the assurance that they precisely correspond to the number described by their binary form. The purpose is to guarantee that a non interval number is exact, so that ExactReal can be used with Interval without producing the "NG" flag.
An ExactReal is constructed by wrapping the value with exact.
See also: @exact
By using ExactReal, users acknowledge the responsibility of ensuring that the number they input corresponds to their intended value. For example, exact(0.1) implies that the user knows that $0.1$ can not be represented exactly as a binary number, and that they are using a slightly different number than $0.1$. To help identify the binary number, ExactReal is displayed without any rounding up to 2000 decimals.
julia> exact(0.1)
ExactReal{Float64}(0.1000000000000000055511151231257827021181583404541015625)In case of doubt, has_exact_display can be use to check if the string representation of a Real is equal to its binary value (up to 2000 decimals).
Examples
julia> using IntervalArithmetic
julia> setdisplay(:full);
julia> 0.5 * interval(1)
Interval{Float64}(0.5, 0.5, com, false)
julia> exact(0.5) * interval(1)
Interval{Float64}(0.5, 0.5, com, true)
julia> setdisplay(:infsup);
julia> [1, interval(2)]
2-element Vector{Interval{Float64}}:
[1.0, 1.0]_com_NG
[2.0, 2.0]_com
julia> [exact(1), interval(2)]
2-element Vector{Interval{Float64}}:
[1.0, 1.0]_com
[2.0, 2.0]_comSee also: @exact.
IntervalArithmetic.Interval — Type
Interval{T<:NumTypes} <: RealInterval type for guaranteed computation with interval arithmetic according to the IEEE Standard 1788-2015. This structure combines a BareInterval together with a Decoration.
Fields:
bareinterval :: BareInterval{T}decoration :: Decorationisguaranteed :: Bool
Constructors compliant with the IEEE Standard 1788-2015:
IntervalArithmetic.Piecewise — Type
Piecewise(pairs... ; continuity = fill(-1, length(pairs) - 1))A function defined by pieces (each associating a domain to a function). Support both intervals and standard numbers.
julia> using IntervalArithmetic
julia> setdisplay(:full);
julia> myabs = Piecewise(
Domain{:open, :closed}(-Inf, 0) => x -> -x,
Domain{:open, :open}(0, Inf) => identity
);
julia> myabs(-22.3)
22.3
julia> myabs(interval(-5, 5))
Interval{Float64}(0.0, 5.0, def, true)For constant pieces, it is recommended to use Constant for full compatibility with intervals.
The domains must be specified in increasing order and must not overlap.
The continuity optional argument takes a vector of N - 1 integers (where N is the number of domains) determining how the piecewise function behaves at the endpoints between the subdomains. The possibility are:
-1: the function is discontinuous between the domains.0: the function is continuous but not differentiable between the domains.n > 0: the function isntimes continuously differentiable between the domains. This only matter when usingForwardDiffto compute derivative of the function.
This information is used to determine the decoration of intervals that covers the endpoint of several domains.
If an input interval goes outside the domain of definition of the piecewise function, the output will always have the trivial (trv) decoration. For standard number, it throws a DomainError.
The piecewise function can have a gap between two pieces. In this case, the continuity optional argument is ignored, and interval spanning over the gap always as the trv decoration.
IntervalArithmetic.bareinterval — Method
bareinterval(T, a, b)Create the bare interval $[a, b]$ according to the IEEE Standard 1788-2015. The validity of the interval is checked by is_valid_interval: if true then a BareInterval{T} is constructed, otherwise an empty interval is returned.
Nothing is done to compensate for the fact that floating point literals are rounded to the nearest when parsed (e.g. 0.1). In such cases, parse the string containing the desired value to ensure its tight enclosure.
See also: interval, ±, .. and @I_str.
Examples
julia> using IntervalArithmetic
julia> setdisplay(:full);
julia> bareinterval(1//1, π)
BareInterval{Rational{Int64}}(1//1, 85563208//27235615)
julia> bareinterval(Rational{Int32}, 1//1, π)
BareInterval{Rational{Int32}}(1//1, 85563208//27235615)
julia> bareinterval(1, π)
BareInterval{Float64}(1.0, 3.1415926535897936)
julia> bareinterval(BigFloat, 1, π)
BareInterval{BigFloat}(1.0, 3.141592653589793238462643383279502884197169399375105820974944592307816406286233)IntervalArithmetic.bisect — Method
bisect(x, α=0.5)
bisect(x, i, α=0.5)Split an interval x at a relative position α, where α = 0.5 corresponds to the midpoint.
Split the i-th component of a vector x at a relative position α, where α = 0.5 corresponds to the midpoint.
IntervalArithmetic.cancelminus — Method
cancelminus(x, y; dec = :default)Compute the unique interval z such that y + z == x.
The keywork dec argument controls the decoration of the result. It can be either a specific decoration, or one of two following options: - :default: if at least one of the input intervals is ill, then the result is ill, otherwise it is trv (Section 11.7.1). - :auto: the ouptut has the minimal decoration of the inputs.
Implement the cancelMinus function of the IEEE Standard 1788-2015 (Section 9.2).
IntervalArithmetic.cancelplus — Method
cancelplus(x, y; dec = :default)Compute the unique interval z such that y - z == x; this is semantically equivalent to cancelminus(x, -y).
The keywork dec argument controls the decoration of the result. It can be either a specific decoration, or one of two following options: - :default: if at least one of the input intervals is ill, then the result is ill, otherwise it is trv (Section 11.7.1). - :auto: the ouptut has the minimal decoration of the inputs.
Implement the cancelPlus function of the IEEE Standard 1788-2015 (Section 9.2).
IntervalArithmetic.dist — Method
dist(x, y)Distance between x and y.
IntervalArithmetic.emptyinterval — Method
emptyinterval(T=[default_numtype()])Create an empty interval. This interval is an exception to the fact that the lower bound is larger than the upper one.
Implement the empty function of the IEEE Standard 1788-2015 (Section 10.5.2).
IntervalArithmetic.entireinterval — Method
entireinterval(T=[default_numtype()])Create an interval representing the entire real line, or the entire complex plane if T is complex.
Implement the entire function of the IEEE Standard 1788-2015 (Section 10.5.2).
IntervalArithmetic.extended_div — Method
extended_div(x, y)Two-output division.
Implement the mulRevToPair function of the IEEE Standard 1788-2015 (Section 10.5.5).
IntervalArithmetic.fastpow — Method
fastpow(x, y)A faster implementation of pow(x, y), at the cost of maybe returning a larger interval.
IntervalArithmetic.fastpown — Method
fastpown(x, n)A faster implementation of pown(x, n), at the cost of maybe returning a larger interval.
IntervalArithmetic.has_exact_display — Method
has_exact_display(x::Real)Determine if the display of x up to 2000 decimals is equal to the bitwise value of x. This is famously not true for the float displayed as 0.1.
IntervalArithmetic.hull — Method
hull(x, y; dec = :default)Return the interval hull of the intervals x and y, considered as (extended) sets of real numbers, i.e. the smallest interval that contains all of x and y.
The keywork dec argument controls the decoration of the result. It can be either a specific decoration, or one of two following options: - :default: if at least one of the input intervals is ill, then the result is ill, otherwise it is trv (Section 11.7.1). - :auto: the ouptut has the minimal decoration of the inputs.
Implement the convexHull function of the IEEE Standard 1788-2015 (Section 9.3).
IntervalArithmetic.in_interval — Method
in_interval(x, y)Test whether x is an element of y.
Implement the isMember function of the IEEE Standard 1788-2015 (Sections 10.6.3 and 12.13.3).
IntervalArithmetic.interiordiff — Method
interiordiff(x, y; dec = :default)Remove the interior of y from x. If x and y are vectors, then they are treated as multi-dimensional intervals.
The keywork dec argument controls the decoration of the result. It can be either a specific decoration, or one of two following options: - :default: if at least one of the input intervals is ill, then the result is ill, otherwise it is trv (Section 11.7.1). - :auto: the ouptut has the minimal decoration of the inputs.
IntervalArithmetic.intersect_interval — Method
intersect_interval(x, y; dec = :default)Returns the intersection of the intervals x and y, considered as (extended) sets of real numbers. That is, the set that contains the points common in x and y.
The keywork dec argument controls the decoration of the result. It can be either a specific decoration, or one of two following options: - :default: if at least one of the input intervals is ill, then the result is ill, otherwise it is trv (Section 11.7.1). - :auto: the ouptut has the minimal decoration of the inputs.
Implement the intersection function of the IEEE Standard 1788-2015 (Section 9.3).
IntervalArithmetic.interval — Method
interval([T,] a, b, d = com; format = :infsup)Create the interval $[a, b]$ according to the IEEE Standard 1788-2015. The validity of the interval is checked by is_valid_interval: if true then an Interval{T} is constructed, otherwise an NaI (Not an Interval) is returned.
Nothing is done to compensate for the fact that floating point literals are rounded to the nearest when parsed (e.g. 0.1). In such cases, parse the string containing the desired value to ensure its tight enclosure.
Examples
julia> using IntervalArithmetic
julia> setdisplay(:full);
julia> interval(1//1, π)
Interval{Rational{Int64}}(1//1, 85563208//27235615, com, true)
julia> interval(Rational{Int32}, 1//1, π)
Interval{Rational{Int32}}(1//1, 85563208//27235615, com, true)
julia> interval(1, π)
Interval{Float64}(1.0, 3.1415926535897936, com, true)
julia> interval(BigFloat, 1, π)
Interval{BigFloat}(1.0, 3.141592653589793238462643383279502884197169399375105820974944592307816406286233, com, true)IntervalArithmetic.isatomic — Method
isatomic(x)Test whether x is unable to be split. This occurs if the interval is empty, or if its lower and upper bounds are equal, or if the bounds are consecutive floating-point numbers.
IntervalArithmetic.isbounded — Method
isbounded(x)Test whether x is empty or has finite bounds.
IntervalArithmetic.iscommon — Method
iscommon(x)Test whether x is not empty and bounded.
Implement the isCommonInterval function of the IEEE Standard 1788-2015 (Sections 10.6.3 and 12.13.3).
IntervalArithmetic.isdisjoint_interval — Method
isdisjoint_interval(x, y, z...)Test whether the given intervals have no common elements.
Implement the disjoint function of the IEEE Standard 1788-2015. (Tables 9.3 and 10.3, and Sections 9.5, 10.5.10 and 12.12.9).
IntervalArithmetic.isempty_interval — Method
isempty_interval(x)Test whether x contains no elements.
Implement the isEmpty function of the IEEE Standard 1788-2015 (Sections 10.5.10 and 12.12.9).
IntervalArithmetic.isentire_interval — Method
isentire_interval(x)Test whether x is the entire real line.
Implement the isEntire function of the IEEE Standard 1788-2015 (Sections 10.5.10 and 12.12.9).
IntervalArithmetic.isequal_interval — Method
isequal_interval(x, y)Test whether x and y are identical.
Implement the equal function of the IEEE Standard 1788-2015 (Tables 9.3 and 10.3, and Sections 9.5, 10.5.10 and 12.12.9).
IntervalArithmetic.isguaranteed — Method
isguaranteed(x::BareInterval)
isguaranteed(x::Interval)
isguaranteed(x::Complex{<:Interval})Test whether the interval is not guaranteed to encompass all possible numerical errors. This happens whenever an Interval is constructed using convert(::Type{<:Interval}, ::Real), which may occur implicitly when mixing intervals and Real types.
Since conversion between BareInterval and Number is prohibited, this implies that isguaranteed(::BareInterval) == true.
In the case of a complex interval x, this is semantically equivalent to isguaranteed(real(x)) & isguaranteed(imag(x)).
Examples
julia> using IntervalArithmetic
julia> isguaranteed(bareinterval(1))
true
julia> isguaranteed(interval(1))
true
julia> isguaranteed(convert(Interval{Float64}, 1))
false
julia> isguaranteed(interval(1) + 0)
falseIntervalArithmetic.isinterior — Method
isinterior(x, y)Test whether x is in the interior of y.
Implement the interior function of the IEEE Standard 1788-2015 (Tables 9.3 and 10.3, and Sections 9.5, 10.5.10 and 12.12.9).
See also: issubset_interval and isstrictsubset.
IntervalArithmetic.isnai — Method
isnai(x)Test whether x is an NaI (Not an Interval).
Implement the isNaI function of the IEEE Standard 1788-2015 (Section 12.12.9).
IntervalArithmetic.issetequal_interval — Function
issetequal_interval(x, y)Return whether the two interval are identical when considered as sets.
Alias of the isequal_interval function.
IntervalArithmetic.isstrictless — Method
isstrictless(x, y)Test whether inf(x) < inf(y) and sup(x) < sup(y), where < is replaced by ≤ for infinite values.
Implement the strictLess function of the IEEE Standard 1788-2015 (Table 10.3, and Sections 10.5.10 and 12.12.9).
IntervalArithmetic.isstrictsubset — Method
isstrictsubset(x, y)Test whether x is a subset of, but not equal to, y. If x and y are vectors, x must be a subset of y with at least one of their component being a strict subset.
See also: issubset_interval and isinterior.
IntervalArithmetic.issubset_interval — Method
issubset_interval(x, y)Test whether x is contained in y.
Implement the subset function of the IEEE Standard 1788-2015 (Tables 9.3 and 10.3, and Sections 9.5, 10.5.10 and 12.12.9).
See also: isstrictsubset and isinterior.
IntervalArithmetic.isthin — Method
isthin(x, y)Test whether x contains only y.
IntervalArithmetic.isthin — Method
isthin(x)Test whether x contains only a real.
Implement the isSingleton function of the IEEE Standard 1788-2015 (Sections 10.6.3 and 12.13.3).
IntervalArithmetic.isthininteger — Method
isthininteger(x)Test whether x contains only an integer.
IntervalArithmetic.isthinone — Method
isthinone(x)Test whether x contains only one.
IntervalArithmetic.isthinzero — Method
isthinzero(x)Test whether x contains only zero.
IntervalArithmetic.isunbounded — Method
isunbounded(x)Test whether x is not empty and has infinite bounds.
IntervalArithmetic.isweakless — Method
isweakless(x, y)Test whether inf(x) ≤ inf(y) and sup(x) ≤ sup(y), where < is replaced by ≤ for infinite values.
Implement the less function of the IEEE Standard 1788-2015 (Table 10.3, and Sections 10.5.10 and 12.12.9).
IntervalArithmetic.mag — Method
mag(x)Magnitude of x.
Implement the mag function of the IEEE Standard 1788-2015 (Table 9.2).
See also: mig.
IntervalArithmetic.mid — Method
mid(x, α = 0.5)Relative midpoint of x, for α between 0 and 1 such that mid(x, 0) is the lower bound of the interval, mid(x, 1) its upper bound, and mid(x, 0.5) its midpoint.
Implement the mid function of the IEEE Standard 1788-2015 (Table 9.2).
IntervalArithmetic.mig — Method
mig(x)Mignitude of x.
Implement the mig function of the IEEE Standard 1788-2015 (Table 9.2).
See also: mag.
IntervalArithmetic.mince! — Method
mince!(v, x, n)In-place version of mince.
IntervalArithmetic.mince — Method
mince(x, n)Split an interval x in n intervals of the same diameter.
Split the i-th component of a vector x in n[i] intervals of the same diameter; n can be a tuple of integers, or a single integer in which case the same n is used for all the components of x.
IntervalArithmetic.nai — Method
nai(T=[default_numtype()])Create an NaI (Not an Interval).
IntervalArithmetic.numtype — Method
numtype(T)Return the bound type of the interval.
Examples
julia> numtype(interval(1, 2))
Float64
julia> numtype(interval(Float32, 1, 2))
Float32IntervalArithmetic.overlap — Method
overlap(x::BareInterval, y::BareInterval)
overlap(x::Interval, y::Interval)Implement the overlap function of the IEEE Standard 1788-2015 (Table 10.7).
IntervalArithmetic.pow — Method
pow(x, y)Compute the power of the positive real part of x by y. In particular, even if y is a thin integer, this is not equivalent to pown(x, sup(y)).
Implement the pow function of the IEEE Standard 1788-2015 (Table 9.1).
See also: fastpow, pown and fastpown.
Examples
julia> using IntervalArithmetic
julia> setdisplay(:full);
julia> pow(bareinterval(2, 3), bareinterval(2))
BareInterval{Float64}(4.0, 9.0)
julia> pow(interval(-1, 1), interval(3))
Interval{Float64}(0.0, 1.0, trv, true)
julia> pow(interval(-1, 1), interval(-3))
Interval{Float64}(1.0, Inf, trv, true)IntervalArithmetic.pown — Method
pown(x, n)Implement the pown function of the IEEE Standard 1788-2015 (Table 9.1).
See also: fastpown, pow and fastpow.
Examples
julia> using IntervalArithmetic
julia> setdisplay(:full);
julia> pown(bareinterval(2, 3), 2)
BareInterval{Float64}(4.0, 9.0)
julia> pown(interval(-1, 1), 3)
Interval{Float64}(-1.0, 1.0, com, true)
julia> pown(interval(-1, 1), -3)
Interval{Float64}(-Inf, Inf, trv, true)IntervalArithmetic.precedes — Method
precedes(x, y)Test whether any element of x is lesser or equal to every elements of y.
Implement the precedes function of the IEEE Standard 1788-2015 (Table 10.3, and Sections 10.5.10 and 12.12.9).
IntervalArithmetic.radius — Method
radius(x)Radius of x, such that issubset_interval(x, mid(x) ± radius(x)). If x is complex, then the radius is the maximum radius between its real and imaginary parts.
Implement the rad function of the IEEE Standard 1788-2015 (Table 9.2).
IntervalArithmetic.rootn — Method
rootn(x::BareInterval, n::Integer)Compute the real n-th root of x.
Implement the rootn function of the IEEE Standard 1788-2015 (Table 9.1).
IntervalArithmetic.setdisplay — Function
setdisplay(format::Symbol; decorations::Bool, ng_flag::Bool, sigdigits::Int)Change the format used by show to display intervals.
Possible options:
formatcan be::infsup: display intervals as[a, b].:midpoint: display intervals asm ± r.:full: display interval bounds entirely, ignoringsigdigits.
decorations: display the decorations or not.ng_flag: display the NG flag or not.sigdigits: number (greater or equal to 1) of significant digits to display.
Initially, the display options are set to setdisplay(:infsup; decorations = true, ng_flag = true, sigdigits = 6). If any of format, decorations, ng_flag and sigdigits is omitted, then their value is left unchanged.
Examples
julia> using IntervalArithmetic
julia> setdisplay(:full)
Display options:
- format: full
- decorations: true (ignored)
- NG flag: true (ignored)
- significant digits: 6 (ignored)
julia> x = interval(0.1, 0.3)
Interval{Float64}(0.1, 0.3, com, true)
julia> setdisplay(:infsup; sigdigits = 3)
Display options:
- format: infsup
- decorations: true
- NG flag: true
- significant digits: 3
julia> x
[0.1, 0.3]_com
julia> setdisplay(; decorations = false)
Display options:
- format: infsup
- decorations: false
- NG flag: true
- significant digits: 3
julia> x
[0.1, 0.3]
julia> setdisplay(:infsup; decorations = true, ng_flag = true, sigdigits = 6) # default display options
Display options:
- format: infsup
- decorations: true
- NG flag: true
- significant digits: 6
julia> x
[0.1, 0.3]_comIntervalArithmetic.strictprecedes — Method
strictprecedes(x, y)Test whether any element of x is strictly lesser than every elements of y.
Implement the strictPrecedes function of the IEEE Standard 1788-2015 (Table 10.3, and Sections 10.5.10 and 12.12.9).
IntervalArithmetic.union_interval — Function
union_interval(x, y, z...)Alias of hull.
IntervalArithmetic.@I_str — Macro
I"str"Create an interval by parsing the string "str"; this is semantically equivalent to parse(Interval{default_numtype()}, "str").
Examples
julia> using IntervalArithmetic
julia> setdisplay(:full);
julia> I"[3, 4]"
Interval{Float64}(3.0, 4.0, com, true)
julia> I"0.1"
Interval{Float64}(0.09999999999999999, 0.1, com, true)
julia> in_interval(1//10, I"0.1")
trueIntervalArithmetic.@exact — Macro
@exactWrap every literal numbers of the expression in an ExactReal. This macro allows defining generic functions, seamlessly accepting both Number and Interval arguments, without producing the "NG" flag.
By using ExactReal, users acknowledge the responsibility of ensuring that the number they input corresponds to their intended value. For example, exact(0.1) implies that the user knows that $0.1$ can not be represented exactly as a binary number, and that they are using a slightly different number than $0.1$. To help identify the binary number, ExactReal is displayed without any rounding up to 2000 decimals.
julia> exact(0.1)
ExactReal{Float64}(0.1000000000000000055511151231257827021181583404541015625)In case of doubt, has_exact_display can be use to check if the string representation of a Real is equal to its binary value (up to 2000 decimals).
Examples
julia> using IntervalArithmetic
julia> setdisplay(:infsup);
julia> f(x) = 1.2 * x + 0.1
f (generic function with 1 method)
julia> f(interval(1, 2))
[1.3, 2.5]_com_NG
julia> @exact g(x) = 1.2 * x + 0.1
g (generic function with 1 method)
julia> g(interval(1, 2))
[1.3, 2.5]_com
julia> g(1.4)
1.78See also: ExactReal.
IntervalArithmetic.@interval — Macro
@interval([T], expr)
@interval([T], expr1, expr2)Walk through an expression and wrap each argument of functions with the internal constructor atomic.
Examples
julia> using IntervalArithmetic
julia> setdisplay(:full);
julia> @interval sin(1) # Float64 is the default bound type
Interval{Float64}(0.8414709848078965, 0.8414709848078966, com, true)
julia> @interval Float32 sin(1)
Interval{Float32}(0.84147096f0, 0.841471f0, com, true)
julia> @interval Float64 sin(1) exp(1)
Interval{Float64}(0.8414709848078965, 2.7182818284590455, com, true)