Skip to content

Commit

Permalink
add cache to Intersection containing emptiness status
Browse files Browse the repository at this point in the history
  • Loading branch information
schillic committed Oct 14, 2018
1 parent d9e8959 commit af30c2c
Showing 1 changed file with 98 additions and 8 deletions.
106 changes: 98 additions & 8 deletions src/Intersection.jl
Original file line number Diff line number Diff line change
@@ -1,23 +1,62 @@
import Base: isempty, ,

export Intersection,
isempty_known,
set_isempty!,
IntersectionArray,
array

"""
IntersectionCache
Container for information cached by a lazy `Intersection` object.
### Fields
- `isempty` -- is the intersection empty? There are three possible states,
encoded as `Int8` values -1, 0, 1:
* ``-1`` - it is currently unknown whether the intersection is empty or not
* ``0`` - intersection is not empty
* ``1`` - intersection is empty
"""
mutable struct IntersectionCache
isempty::Int8

# default constructor
IntersectionCache() = new(Int8(-1))
end

function isempty_known(c::IntersectionCache)::Bool
return c.isempty != Int8(-1)
end

function isempty(c::IntersectionCache)::Bool
@assert isempty_known(c) "'isempty_known' only works if 'isempty' " *
"returns 'true'"
return c.isempty == Int8(1)
end

function set_isempty!(c::IntersectionCache, isempty::Bool)
c.isempty = isempty ? Int8(1) : Int8(0)
end

"""
Intersection{N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} <: LazySet{N}
Type that represents the intersection of two convex sets.
### Fields
- `X` -- convex set
- `Y` -- convex set
- `X` -- convex set
- `Y` -- convex set
- `cache` -- internal cache for avoiding recomputation; see
[`IntersectionCache`](@ref)
### Examples
Create an expression, ``Z``, that lazily represents the intersection of two squares
``X`` and ``Y``:
Create an expression, ``Z``, which lazily represents the intersection of two
squares ``X`` and ``Y``:
```jldoctest lazy_intersection
julia> X, Y = BallInf([0,0.], 0.5), BallInf([1,0.], 0.65);
Expand All @@ -38,8 +77,8 @@ julia> isempty(Z)
false
```
Do not confuse `Intersection` with the concrete operation, that is computed with
the lowercase `intersection`:
Do not confuse `Intersection` with the concrete operation, which is computed
with the lowercase `intersection` function:
```jldoctest lazy_intersection
julia> W = intersection(X, Y)
Expand All @@ -49,13 +88,14 @@ Hyperrectangle{Float64}([0.425, 0.0], [0.075, 0.5])
struct Intersection{N<:Real, S1<:LazySet{N}, S2<:LazySet{N}} <: LazySet{N}
X::S1
Y::S2
cache::IntersectionCache

# default constructor with dimension check
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{N, S1, S2}(X, Y)
return new{N, S1, S2}(X, Y, IntersectionCache())
end
end

Expand All @@ -74,6 +114,42 @@ Alias for `Intersection`.
(X::LazySet, Y::LazySet) = Intersection(X, Y)


# --- cache propagation functions ---


"""
isempty_known(cap::Intersection)
Ask whether the status of emptiness is known.
### Input
- `cap` -- intersection of two convex sets
### Output
`true` iff the emptiness status is known.
In this case, `isempty(cap)` can be used to obtain the status.
"""
function isempty_known(cap::Intersection)
return isempty_known(cap.cache)
end

"""
set_isempty!(cap::Intersection, isempty::Bool)
Set the status of emptiness in the cache.
### Input
- `cap` -- intersection of two convex sets
- `isempty` -- new status of emptiness
"""
function set_isempty!(cap::Intersection, isempty::Bool)
return set_isempty!(cap.cache, isempty)
end


# --- LazySet interface functions ---


Expand Down Expand Up @@ -370,16 +446,30 @@ Return if the intersection is empty or not.
### Output
`true` iff the intersection is empty.
### Notes
The result will be cached, so a second query will be fast.
"""
function isempty(cap::Intersection)::Bool
return is_intersection_empty(cap.X, cap.Y)
if isempty_known(cap.cache)
# use cached result
return isempty(cap.cache)
end
# compute result
empty_intersection = is_intersection_empty(cap.X, cap.Y)
# update cache
set_isempty!(cap, empty_intersection)

return empty_intersection
end


# ================================
# intersection of an array of sets
# ================================


"""
IntersectionArray{N<:Real, S<:LazySet{N}} <: LazySet{N}
Expand Down

0 comments on commit af30c2c

Please sign in to comment.