@@ -1215,3 +1215,73 @@ function _overapproximate_zonotope_hyperplane(Z::AbstractZonotope, H::Hyperplane
1215
1215
G_cap = G * Gs
1216
1216
return Zonotope (c_cap, G_cap)
1217
1217
end
1218
+
1219
+ function overapproximate (X:: Intersection{N,<:AbstractZonotope,<:HalfSpace{N,<:SingleEntryVector}} ,
1220
+ :: Type{Zonotope} ) where {N}
1221
+ return _overapproximate_zonotope_halfspace_ICP (first (X), second (X))
1222
+ end
1223
+
1224
+ # symmetric method
1225
+ function overapproximate (X:: Intersection{N,<:HalfSpace{N,<:SingleEntryVector},<:AbstractZonotope} ,
1226
+ :: Type{Zonotope} ) where {N}
1227
+ return _overapproximate_zonotope_halfspace_ICP (second (X), first (X))
1228
+ end
1229
+
1230
+ # method for a single constraint of the form x_i <= b based on ICP
1231
+ # - zonotope = G * []^p + c, where []^p is the p-dimensional unit cube
1232
+ # - let G_i be the i-th row of G
1233
+ # - build an ICP contractor for the constraint G_i^T x <= b - c
1234
+ # - contract the domain of []^p under this constraint to D
1235
+ # - the resulting zonotope is G * D + c
1236
+ function _overapproximate_zonotope_halfspace_ICP (Z:: AbstractZonotope{N} ,
1237
+ H:: HalfSpace{N,SingleEntryVector{N}} ) where {N}
1238
+ c = center (Z)
1239
+ G = genmat (Z)
1240
+ p = size (G, 2 )
1241
+ d = H. a. i
1242
+
1243
+ a = G[d, :]
1244
+ io = IOBuffer ()
1245
+ first = true
1246
+ v = H. a. v
1247
+ negate = v < zero (N)
1248
+ if negate
1249
+ v = - v
1250
+ end
1251
+ for (i, ai) in enumerate (a)
1252
+ if first
1253
+ first = false
1254
+ elseif ai >= 0
1255
+ write (io, " +" )
1256
+ end
1257
+ write (io, " $(v * ai) *x$(i) " )
1258
+ end
1259
+ if negate
1260
+ write (io, " >=$(- H. b + c[d]) " )
1261
+ else
1262
+ write (io, " <=$(H. b - c[d]) " )
1263
+ end
1264
+ e = Meta. parse (String (take! (io)))
1265
+ X = IA. IntervalBox (IA. interval (- 1 , 1 ), p)
1266
+ newD = _contract_zonotope_halfspace_ICP (e, X)
1267
+ if isempty (newD)
1268
+ return EmptySet {N} (length (c))
1269
+ end
1270
+ return affine_map (G, convert (Hyperrectangle, newD), c)
1271
+ end
1272
+
1273
+ function load_overapproximate_ICP ()
1274
+ return quote
1275
+ import . IntervalConstraintProgramming as ICP
1276
+
1277
+ function _contract_zonotope_halfspace_ICP (e, X)
1278
+ separator = eval (quote
1279
+ ICP. @constraint $ e
1280
+ end )
1281
+ # smallest box containing all points in domain X satisfying constraint
1282
+ # (`invokelatest` to avoid world-age issue; `Base.` for VERSION < v"1.9")
1283
+ out, _ = Base. invokelatest (separator, X)
1284
+ return out
1285
+ end
1286
+ end
1287
+ end # load_overapproximate_ICP()
0 commit comments