Repository: JuliaReach/ReachabilityAnalysis.jl (julia)

Issue:
Fix type piracy for "set" wrt LazySets
Required fixes:

- [x] set
- [x] array (eg. when using a CPA)

Pull request description:
Closes https://github.com/JuliaReach/ReachabilityAnalysis.jl/issues/254.

Patch:
diff --git a/src/Flowpipes/reachsets.jl b/src/Flowpipes/reachsets.jl
index 9c29059646..3cf8c3aefc 100644
--- a/src/Flowpipes/reachsets.jl
+++ b/src/Flowpipes/reachsets.jl
@@ -664,6 +664,7 @@ function overapproximate(R::TaylorModelReachSet{N}, ::Type{<:Hyperrectangle}) wh
     return ReachSet(X̂, Δt)
 end
 
+# overapproximate taylor model reachset with several hyperrectangles
 function overapproximate(R::TaylorModelReachSet{N}, ::Type{<:Hyperrectangle}, nparts) where {N}
     # dimension of the reachset
     D = dim(R)
@@ -691,6 +692,7 @@ function overapproximate(R::TaylorModelReachSet{N}, ::Type{<:Hyperrectangle}, np
     return ReachSet(ConvexHullArray(X̂), Δt)
 end
 
+# overapproximate taylor model reachset with one zonotope
 function overapproximate(R::TaylorModelReachSet{N}, ::Type{<:Zonotope}) where {N}
     # dimension of the reachset
     n = dim(R)
@@ -721,6 +723,7 @@ function overapproximate(R::TaylorModelReachSet{N}, ::Type{<:Zonotope}) where {N
     return ReachSet(Zi, Δt)
 end
 
+# convert a hyperrectangular set to a taylor model reachset
 function convert(::Type{<:TaylorModelReachSet}, H::AbstractHyperrectangle{N};
                  orderQ::Integer=2, orderT::Integer=8, Δt::TimeInterval=zeroI) where {N}
 
@@ -742,11 +745,13 @@ function convert(::Type{<:TaylorModelReachSet}, H::AbstractHyperrectangle{N};
     return TaylorModelReachSet(vTM, Δt)
 end
 
+# overapproximate a hyperrectangular set with a taylor model reachset, fallback to convert
 function overapproximate(H::AbstractHyperrectangle{N}, T::Type{<:TaylorModelReachSet};
                          orderQ::Integer=2, orderT::Integer=8, Δt::TimeInterval=zeroI) where {N}
     convert(T, H; orderQ=orderQ, orderT=orderT, Δt=Δt)
 end
 
+# overapproximate a zonotopic set with a taylor model reachset
 function overapproximate(Z::AbstractZonotope{N}, ::Type{<:TaylorModelReachSet};
                          orderQ::Integer=2, orderT::Integer=8, Δt::TimeInterval=zeroI,
                          indices=1:dim(Z)) where {N}
@@ -777,6 +782,25 @@ function overapproximate(Z::AbstractZonotope{N}, ::Type{<:TaylorModelReachSet};
     return TaylorModelReachSet(vTM, Δt)
 end
 
+# convert a zonotopic set to a taylor model reachset (only if it has order 1)
+function convert(TM::Type{<:TaylorModelReachSet}, Z::AbstractZonotope; kwargs...)
+    if order(Z) == 1
+        return overapproximate(Z, TM; kwargs...)
+
+    else
+        throw(ArgumentError("can't convert a zonotope of order $(order(Z)) to a `TaylorModelReachSet`; " *
+                            "use `overapproximate(Z, TaylorModelReachSet)` instead"))
+    end
+end
+
+function convert(TM::Type{<:TaylorModelReachSet}, R::AbstractLazyReachSet; kwargs...)
+    return convert(TM, set(R); Δt=tspan(R), kwargs...)
+end
+
+function overapproximate(R::AbstractLazyReachSet, TM::Type{<:TaylorModelReachSet}; kwargs...)
+    return overapproximate(set(R), TM; Δt=tspan(R), kwargs...)
+end
+
 # ================================================================
 # Template reach set
 # ================================================================
diff --git a/src/Initialization/init.jl b/src/Initialization/init.jl
index 5454ca2dac..1284fafc83 100644
--- a/src/Initialization/init.jl
+++ b/src/Initialization/init.jl
@@ -56,7 +56,7 @@ const AdmissibleSet = Union{LazySet, UnionSet, UnionSetArray, IA.Interval, IA.In
 
 # method extensions
 import LazySets: dim, overapproximate, project, Projection,
-                 linear_map, LinearMap, _split, split!
+                 linear_map, LinearMap, _split, split!, set, array
 
 import Base: ∈, convert
 


Test patch:
diff --git a/test/reachsets.jl b/test/reachsets.jl
index d812634592..21dbc120db 100644
--- a/test/reachsets.jl
+++ b/test/reachsets.jl
@@ -47,3 +47,38 @@
     p4 = Projection(R, vars=[0, 1]);
     @test all(x -> isequivalent(Bt, overapproximate(set(x), Hyperrectangle)), [p1, p2, p3, p4])
 end
+
+@testset "Conversion of Taylor model reach-sets" begin
+    H = Hyperrectangle(ones(2), [0.2, 0.4])
+    a = overapproximate(H, TaylorModelReachSet)
+    b = convert(TaylorModelReachSet, H)
+
+    @test tspan(a) == tspan(b) == 0 .. 0
+    @test isequivalent(set(overapproximate(a, Hyperrectangle)), H)
+    @test isequivalent(set(overapproximate(b, Hyperrectangle)), H)
+
+    R = ReachSet(H, 0 .. 1)
+    c = overapproximate(R, TaylorModelReachSet)
+    d = convert(TaylorModelReachSet, R)
+
+    @test tspan(c) == tspan(d) == 0..1
+    @test isequivalent(set(overapproximate(c, Hyperrectangle)), set(R))
+    @test isequivalent(set(overapproximate(d, Hyperrectangle)), set(R))
+
+    Z = convert(Zonotope, H)
+    a = overapproximate(Z, TaylorModelReachSet)
+    b = convert(TaylorModelReachSet, Z)
+
+    @test tspan(a) == tspan(b) == 0 .. 0
+    @test isequivalent(set(overapproximate(a, Zonotope)), Z)
+    @test isequivalent(set(overapproximate(b, Zonotope)), Z)
+
+    R = ReachSet(Z, 0 .. 1)
+    c = overapproximate(R, TaylorModelReachSet)
+    d = convert(TaylorModelReachSet, R)
+
+    @test tspan(c) == tspan(d) == 0..1
+    @test isequivalent(set(overapproximate(c, Zonotope)), set(R))
+    @test isequivalent(set(overapproximate(d, Zonotope)), set(R))
+
+end