diff --git a/src/AbstractHPolygon.jl b/src/AbstractHPolygon.jl index 32af187489..6f76eccdca 100644 --- a/src/AbstractHPolygon.jl +++ b/src/AbstractHPolygon.jl @@ -139,9 +139,7 @@ A vertex of the polygon in constraint representation (the first one in the order of the constraints). """ function an_element(P::AbstractHPolygon{N})::Vector{N} where {N<:Real} - if length(P.constraints) < 2 - error("a polygon in constraint representation should have at least two constraints") - end + @assert length(P.constraints) >= 2 "polygon has less than two constraints" return intersection(Line(P.constraints[1]), Line(P.constraints[2])) end diff --git a/src/Ball1.jl b/src/Ball1.jl index a87643d619..bb7a4641d3 100644 --- a/src/Ball1.jl +++ b/src/Ball1.jl @@ -45,8 +45,10 @@ struct Ball1{N<:Real} <: AbstractPointSymmetricPolytope{N} radius::N # default constructor with domain constraint for radius - Ball1{N}(center, radius) where N = - radius < zero(N) ? throw(DomainError()) : new(center, radius) + function Ball1{N}(center, radius) where N + @assert radius >= zero(N) "radius must not be negative" + return new(center, radius) + end end # type-less convenience constructor Ball1(center::Vector{N}, radius::N) where {N<:Real} = Ball1{N}(center, radius) diff --git a/src/Ball2.jl b/src/Ball2.jl index 78f3570feb..dc33a322c6 100644 --- a/src/Ball2.jl +++ b/src/Ball2.jl @@ -53,8 +53,10 @@ struct Ball2{N<:AbstractFloat} <: AbstractPointSymmetric{N} radius::N # default constructor with domain constraint for radius - Ball2{N}(center, radius) where N = - radius < zero(N) ? throw(DomainError()) : new(center, radius) + function Ball2{N}(center, radius) where N + @assert radius >= zero(N) "radius must not be negative" + return new(center, radius) + end end # type-less convenience constructor Ball2(center::Vector{N}, radius::N) where {N<:AbstractFloat} = diff --git a/src/BallInf.jl b/src/BallInf.jl index d127b1760d..ff0cd9b4d5 100644 --- a/src/BallInf.jl +++ b/src/BallInf.jl @@ -41,8 +41,10 @@ struct BallInf{N<:Real} <: AbstractHyperrectangle{N} radius::N # default constructor with domain constraint for radius - BallInf{N}(center, radius) where N = - radius < zero(N) ? throw(DomainError()) : new(center, radius) + function BallInf{N}(center, radius) where N + @assert radius >= zero(N) "radius must not be negative" + return new(center, radius) + end end # type-less convenience constructor BallInf(center::Vector{N}, radius::N) where {N<:Real} = diff --git a/src/Ballp.jl b/src/Ballp.jl index 2643f0decb..e7ec077524 100644 --- a/src/Ballp.jl +++ b/src/Ballp.jl @@ -57,20 +57,18 @@ struct Ballp{N<:AbstractFloat} <: AbstractPointSymmetric{N} center::Vector{N} radius::N + # default constructor with domain constraint for radius and p function Ballp{N}(p, center, radius) where N - if radius < zero(N) - throw(DomainError()) - end + @assert radius >= zero(N) "radius must not be negative" + @assert p >= 1 "p must not be less than 1" if p == Inf return BallInf(center, radius) elseif p == 2 return Ball2(center, radius) elseif p == 1 return Ball1(center, radius) - elseif 1 < p && p < Inf - new(p, center, radius) else - throw(DomainError()) + return new(p, center, radius) end end end diff --git a/src/ConvexHull.jl b/src/ConvexHull.jl index 4d2b95dfed..f8c572b9b7 100644 --- a/src/ConvexHull.jl +++ b/src/ConvexHull.jl @@ -39,9 +39,12 @@ struct ConvexHull{N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} <: LazySet{N} Y::S2 # default constructor with dimension check - ConvexHull{N, S1, S2}(X::S1, Y::S2) where - {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} = - dim(X) != dim(Y) ? throw(DimensionMismatch) : new(X, Y) + function ConvexHull{N, S1, S2}(X::S1, Y::S2) where + {N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} + @assert dim(X) == dim(Y) "sets in a convex hull must have the same " * + "dimension" + return new(X, Y) + end end # type-less convenience constructor ConvexHull(X::S1, Y::S2) where {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} = diff --git a/src/HPolygon.jl b/src/HPolygon.jl index e4d694746e..41ab1364d4 100644 --- a/src/HPolygon.jl +++ b/src/HPolygon.jl @@ -63,9 +63,7 @@ Comparison of directions is performed using polar angles; see the overload of """ function σ(d::AbstractVector{<:Real}, P::HPolygon{N})::Vector{N} where {N<:Real} n = length(P.constraints) - if n == 0 - error("this polygon is empty") - end + @assert n > 0 "the polygon has no constraints" k = 1 while k <= n && P.constraints[k].a <= d k += 1 diff --git a/src/HPolygonOpt.jl b/src/HPolygonOpt.jl index 205e52b232..715899244e 100644 --- a/src/HPolygonOpt.jl +++ b/src/HPolygonOpt.jl @@ -82,9 +82,7 @@ Comparison of directions is performed using polar angles; see the overload of function σ(d::AbstractVector{<:Real}, P::HPolygonOpt{N})::Vector{N} where {N<:Real} n = length(P.constraints) - if n == 0 - error("this polygon is empty") - end + @assert n > 0 "the polygon has no constraints" if (d <= P.constraints[P.ind].a) k = P.ind-1 while (k >= 1 && d <= P.constraints[k].a) diff --git a/src/HPolytope.jl b/src/HPolytope.jl index 02d4335a1a..e3de144f0f 100644 --- a/src/HPolytope.jl +++ b/src/HPolytope.jl @@ -85,12 +85,10 @@ This implementation uses `GLPKSolverLP` as linear programming backend. """ function σ(d::AbstractVector{<:Real}, P::HPolytope)::Vector{<:Real} c = -d - m = length(constraints_list(P)) - if m == 0 - error("this polytope is empty") - end - A = zeros(m, dim(P)) - b = zeros(m) + n = length(constraints_list(P)) + @assert n > 0 "the polytope has no constraints" + A = zeros(n, dim(P)) + b = zeros(n) for (i, Pi) in enumerate(constraints_list(P)) A[i, :] = Pi.a b[i] = Pi.b diff --git a/src/Hyperrectangle.jl b/src/Hyperrectangle.jl index 9524948ffd..dd96729dcc 100644 --- a/src/Hyperrectangle.jl +++ b/src/Hyperrectangle.jl @@ -20,11 +20,14 @@ struct Hyperrectangle{N<:Real} <: AbstractHyperrectangle{N} center::Vector{N} radius::Vector{N} - # default constructor with length comparison - Hyperrectangle{N}(center::Vector{N}, radius::Vector{N}) where {N<:Real} = - (length(center) != length(radius) - ? throw(DimensionMismatch) - : new(center, radius)) + # default constructor with length comparison & domain constraint for radius + function Hyperrectangle{N}(center::Vector{N}, + radius::Vector{N}) where {N<:Real} + @assert length(center) == length(radius) "length of center and " * + "radius must be equal" + @assert all(v -> v >= zero(N), radius) "radius must not be negative" + return new(center, radius) + end end # type-less convenience constructor Hyperrectangle(center::Vector{N}, radius::Vector{N}) where {N<:Real} = diff --git a/src/Intersection.jl b/src/Intersection.jl index a8b6668920..3591499ae4 100644 --- a/src/Intersection.jl +++ b/src/Intersection.jl @@ -19,9 +19,12 @@ struct Intersection{N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} <: LazySet{N} Y::S2 # default constructor with dimension check - Intersection{N, S1, S2}(X::S1, Y::S2) where - {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} = - dim(X) != dim(Y) ? throw(DimensionMismatch) : new(X, Y) + function Intersection{N, S1, S2}(X::S1, Y::S2) where + {N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} + @assert dim(X) == dim(Y) "sets in an intersection must have the same " * + "dimension" + return new(X, Y) + end end # type-less convenience constructor Intersection(X::S1, Y::S2) where {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} = diff --git a/src/Line.jl b/src/Line.jl index d8f40ddbef..d41b9cc8c8 100644 --- a/src/Line.jl +++ b/src/Line.jl @@ -25,8 +25,10 @@ struct Line{N<:Real, V<:AbstractVector{N}} <: LazySet{N} b::N # default constructor with length constraint - Line{N, V}(a::V, b::N) where {N<:Real, V<:AbstractVector{N}} = - (length(a) != 2 ? throw(DimensionMismatch) : new{N, V}(a, b)) + function Line{N, V}(a::V, b::N) where {N<:Real, V<:AbstractVector{N}} + @assert length(a) == 2 "lines must be two-dimensional" + return new{N, V}(a, b) + end end # type-less convenience constructor diff --git a/src/LineSegment.jl b/src/LineSegment.jl index 64aefab152..c1b2b301e8 100644 --- a/src/LineSegment.jl +++ b/src/LineSegment.jl @@ -49,8 +49,12 @@ struct LineSegment{N<:Real} <: LazySet{N} q::AbstractVector{N} # default constructor with length constraint - LineSegment{N}(p::AbstractVector{N}, q::AbstractVector{N}) where {N<:Real} = - (length(p) == length(q) == 2 ? new{N}(p, q) : throw(DimensionMismatch)) + function LineSegment{N}(p::AbstractVector{N}, + q::AbstractVector{N}) where {N<:Real} + @assert length(p) == length(q) == 2 "points for line segments must " * + "be two-dimensional" + return new{N}(p, q) + end end # type-less convenience constructor diff --git a/src/MinkowskiSum.jl b/src/MinkowskiSum.jl index 700992c2cf..5ec0ef38d5 100644 --- a/src/MinkowskiSum.jl +++ b/src/MinkowskiSum.jl @@ -26,10 +26,13 @@ struct MinkowskiSum{N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} <: LazySet{N} X::S1 Y::S2 - # default constructor with dimension match check - MinkowskiSum{N, S1, S2}(X::S1, Y::S2) where - {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} = - dim(X) != dim(Y) ? throw(DimensionMismatch) : new(X, Y) + # default constructor with dimension check + function MinkowskiSum{N, S1, S2}(X::S1, Y::S2) where + {N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} + @assert dim(X) == dim(Y) "sets in a Minkowski sum must have the " * + "same dimension" + return new(X, Y) + end end # type-less convenience constructor MinkowskiSum(X::S1, Y::S2) where {S1<:LazySet{N}, S2<:LazySet{N}} where {N<:Real} = diff --git a/src/VPolygon.jl b/src/VPolygon.jl index 3b6c48492c..95bcfec084 100644 --- a/src/VPolygon.jl +++ b/src/VPolygon.jl @@ -173,9 +173,7 @@ See issue [#40](https://github.com/JuliaReach/LazySets.jl/issues/40). """ function σ(d::AbstractVector{<:Real}, P::VPolygon{N})::Vector{N} where {N<:Real} - if isempty(P.vertices) - error("this polygon is empty") - end + @assert !isempty(P.vertices) "the polygon has no vertices" i_max = 1 @inbounds for i in 2:length(P.vertices) if dot(d, P.vertices[i] - P.vertices[i_max]) > zero(N) @@ -199,9 +197,7 @@ Return some element of a polygon in vertex representation. The first vertex of the polygon in vertex representation. """ function an_element(P::VPolygon{N})::Vector{N} where {N<:Real} - if isempty(P.vertices) - error("this polygon is empty") - end + @assert !isempty(P.vertices) "the polygon has no vertices" return P.vertices[1] end diff --git a/src/convert.jl b/src/convert.jl index 7c0ff85cd3..c0b9907aa3 100644 --- a/src/convert.jl +++ b/src/convert.jl @@ -60,9 +60,7 @@ The 2D polytope represented as polygon. """ function convert(::Type{HPOLYGON}, P::HPolytope{N}) where {N, HPOLYGON<:AbstractHPolygon} - if dim(P) != 2 - error("polytope must be 2D for conversion") - end + @assert dim(P) == 2 "polytope must be two-dimensional for conversion" H = HPOLYGON{N}() for ci in constraints_list(P) # guarantee that the edges are correctly sorted for storage diff --git a/test/unit_Polygon.jl b/test/unit_Polygon.jl index 976b2003d7..d565f13450 100644 --- a/test/unit_Polygon.jl +++ b/test/unit_Polygon.jl @@ -33,9 +33,9 @@ for N in [Float64, Float32, Rational{Int}] HPolytope(po) # support vector of empty polygon - @test_throws ErrorException σ(N[0.], HPolygon{N}()) - @test_throws ErrorException σ(N[0.], HPolygonOpt(HPolygon{N}())) - @test_throws ErrorException σ(N[0.], HPolytope{N}()) + @test_throws AssertionError σ(N[0.], HPolygon{N}()) + @test_throws AssertionError σ(N[0.], HPolygonOpt(HPolygon{N}())) + @test_throws AssertionError σ(N[0.], HPolytope{N}()) # HPolygon/HPolygonOpt tests for p in [p, po] @@ -71,9 +71,9 @@ for N in [Float64, Float32, Rational{Int}] # an_element function @test an_element(p) ∈ p p_shallow = HPolygon{N}() - @test_throws ErrorException an_element(p_shallow) + @test_throws AssertionError an_element(p_shallow) addconstraint!(p_shallow, c1) - @test_throws ErrorException an_element(p_shallow) + @test_throws AssertionError an_element(p_shallow) # hrep conversion @test tohrep(p) == p