Skip to content

Commit

Permalink
Merge pull request #439 from JuliaReach/schillic/436
Browse files Browse the repository at this point in the history
#436 - Use AbstractMap interface in hybrid models
  • Loading branch information
schillic authored Feb 11, 2019
2 parents 113a3a1 + 3ac7a50 commit a02b8c2
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 31 deletions.
17 changes: 12 additions & 5 deletions src/ReachSets/DiscretePost/ConcreteDiscretePost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,8 @@ function post(𝒫::ConcreteDiscretePost,
target_loc_id = target(HS, trans)
target_loc = HS.modes[target(HS, trans)]
target_invariant = target_loc.X
trans_annot = HS.resetmaps[symbol(HS, trans)]
guard = trans_annot.X
assignment = trans_annot.A
constrained_map = resetmap(HS, trans)
guard = stateset(constrained_map)

# perform jumps
post_jump = Vector{ReachSet{LazySet{N}, N}}()
Expand All @@ -125,8 +124,7 @@ function post(𝒫::ConcreteDiscretePost,
end

# apply assignment
# TODO converting to HPolytope ?? handle automatically ??
A⌜R⋂G⌟ = convert(HPolytope, linear_map(assignment, R⋂G))
A⌜R⋂G⌟ = apply_assignment(𝒫, constrained_map, R⋂G)

# intersect with target invariant
A⌜R⋂G⌟⋂I = intersection(target_invariant, A⌜R⋂G⌟)
Expand All @@ -144,3 +142,12 @@ function post(𝒫::ConcreteDiscretePost,
target_loc_id, jumps)
end
end

# --- handling assignments ---

function apply_assignment(𝒫::ConcreteDiscretePost,
constrained_map::ConstrainedLinearMap,
R⋂G::LazySet;
kwargs...)
return linear_map(constrained_map.A, R⋂G)
end
31 changes: 20 additions & 11 deletions src/ReachSets/DiscretePost/DiscretePost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ Abstract supertype of all discrete post operators.
All discrete post operators should provide the following method, in addition
to those provided for general post operators:
```julia
tube⋂inv!(op::DiscretePost, reach_tube::Vector{<:ReachSet{<:LazySet{N}}},
tube⋂inv!(𝒫::DiscretePost, reach_tube::Vector{<:ReachSet{<:LazySet{N}}},
invariant, Rsets, start_interval)::Vector{ReachSet{LazySet{N}, N}}
```
"""
abstract type DiscretePost <: PostOperator end

function postprocess(op,
function postprocess(𝒫,
HS,
post_jump,
options,
Expand All @@ -29,7 +29,7 @@ function postprocess(op,
if fixpoint_strategy == :eager
# eager fixpoint checking
post_jump_filtered =
filter(x -> !isfixpoint(op, x, passed_list, target_loc_id),
filter(x -> !isfixpoint(𝒫, x, passed_list, target_loc_id),
post_jump)
else
post_jump_filtered = post_jump
Expand All @@ -41,13 +41,13 @@ function postprocess(op,
end

# apply clustering
clustered = cluster(op, post_jump_filtered, options)
clustered = cluster(𝒫, post_jump_filtered, options)

# push new sets after jump (unless a fixpoint is detected)
for reach_set in clustered
if fixpoint_strategy != :none
if fixpoint_strategy == :lazy &&
isfixpoint(op, reach_set, passed_list, target_loc_id)
isfixpoint(𝒫, reach_set, passed_list, target_loc_id)
continue
end
push!(passed_list[target_loc_id], reach_set)
Expand All @@ -56,11 +56,11 @@ function postprocess(op,
end
end

function cluster(op::DiscretePost,
function cluster(𝒫::DiscretePost,
reach_sets::Vector{ReachSet{LazySet{N}, N}},
options::Options) where N<:Real
clustering_strategy = options[:clustering]
dirs = op.options[:overapproximation]
dirs = 𝒫.options[:overapproximation]
if clustering_strategy == :none
# no clustering
return reach_sets
Expand All @@ -76,7 +76,7 @@ function cluster(op::DiscretePost,
end
end

function isfixpoint(op::DiscretePost,
function isfixpoint(𝒫::DiscretePost,
reach_set::ReachSet{LazySet{N}, N},
passed_list,
loc_id
Expand All @@ -97,13 +97,13 @@ function isfixpoint(op::DiscretePost,
end

# default: always apply line search
function use_precise_ρ(op::DiscretePost,
function use_precise_ρ(𝒫::DiscretePost,
cap::Intersection{N})::Bool where N<:Real
return true
end

function get_overapproximation_option(op::DiscretePost, n::Int)
oa = op.options.dict[:overapproximation]
function get_overapproximation_option(𝒫::DiscretePost, n::Int)
oa = 𝒫.options.dict[:overapproximation]
if oa isa Symbol
dirs = Utils.interpret_template_direction_symbol(oa)
return dirs(n)
Expand All @@ -113,3 +113,12 @@ function get_overapproximation_option(op::DiscretePost, n::Int)
error("received unknown :overapproximation option $oa")
end
end

# --- default methods for handling assignments ---

function apply_assignment(𝒫::DiscretePost,
constrained_map::AbstractMap,
R⋂G::LazySet;
kwargs...)
return apply(constrained_map, R⋂G)
end
17 changes: 8 additions & 9 deletions src/ReachSets/DiscretePost/LazyDiscretePost.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,8 @@ function post(𝒫::LazyDiscretePost,
options
) where {N}
jumps += 1
# TODO? dirs = 𝒫.options[:overapproximation]
dirs = get_overapproximation_option(𝒫, options[:n])
# TODO? oa = 𝒫.options[:overapproximation]
oa = get_overapproximation_option(𝒫, options[:n])
source_invariant = HS.modes[source_loc_id].X
inv_isa_Hrep, inv_isa_H_polytope = get_Hrep_info(source_invariant)

Expand All @@ -126,9 +126,8 @@ function post(𝒫::LazyDiscretePost,
target_loc_id = target(HS, trans)
target_loc = HS.modes[target(HS, trans)]
target_invariant = target_loc.X
trans_annot = HS.resetmaps[symbol(HS, trans)]
guard = trans_annot.X
assignment = trans_annot.A
constrained_map = resetmap(HS, trans)
guard = stateset(constrained_map)

if inv_isa_Hrep
guard_isa_Hrep, guard_isa_H_polytope = get_Hrep_info(guard)
Expand Down Expand Up @@ -159,9 +158,9 @@ function post(𝒫::LazyDiscretePost,
end

# apply assignment
A⌜R⋂G⌟ = LinearMap(assignment, R⋂G)
A⌜R⋂G⌟ = apply_assignment(𝒫, constrained_map, R⋂G)
if !𝒫.options[:lazy_R⋂G]
A⌜R⋂G⌟ = overapproximate(A⌜R⋂G⌟, dirs)
A⌜R⋂G⌟ = overapproximate(A⌜R⋂G⌟, oa)
end

# intersect with target invariant
Expand All @@ -174,7 +173,7 @@ function post(𝒫::LazyDiscretePost,

# overapproximate final set once more
if !𝒫.options[:lazy_A⌜R⋂G⌟⋂I]
res = overapproximate(A⌜R⋂G⌟⋂I, dirs)
res = overapproximate(A⌜R⋂G⌟⋂I, oa)
else
res = A⌜R⋂G⌟⋂I
end
Expand Down Expand Up @@ -202,7 +201,7 @@ function get_Hrep_info(set::HPolyhedron)
return (true, false)
end

# --- line search policies ---
# --- line-search policies ---

# usually do not use line search
function use_precise_ρ(𝒫::LazyDiscretePost,
Expand Down
3 changes: 1 addition & 2 deletions test/Reachability/models/bouncing_ball.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ function bouncing_ball()
guard = HPolyhedron([HalfSpace([0.0, 1.0], 0.0), # v ≤ 0
HalfSpace([-1.0, 0.0], 0.0), # x ≥ 0
HalfSpace([1.0, 0.0], 0.0)]) # x ≤ 0
t1 = ConstrainedLinearDiscreteSystem(A, guard) # old interface
# t1 = ConstrainedLinearMap(A, guard) # new interface
t1 = ConstrainedLinearMap(A, guard)

# transition annotations
resetmaps = [t1]
Expand Down
6 changes: 2 additions & 4 deletions test/Reachability/models/thermostat.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,12 @@ function thermostat()
# transition from on to off
add_transition!(automaton, 1, 2, 1)
guard = HalfSpace([-1.0], -21.0) # x ≥ 21
t_on2off = ConstrainedLinearDiscreteSystem(hcat(1.0), guard) # old interface
# t_on2off = ConstrainedIdentityMap(2, guard) # new interface
t_on2off = ConstrainedIdentityMap(2, guard)

# transition from off to on
add_transition!(automaton, 2, 1, 2)
guard = HalfSpace([1.0], 19.0) # x ≤ 19
t_off2on = ConstrainedLinearDiscreteSystem(hcat(1.0), guard) # old interface
# t_off2on = ConstrainedIdentityMap(2, guard) # new interface
t_off2on = ConstrainedIdentityMap(2, guard)

# transition annotations
resetmaps = [t_on2off, t_off2on]
Expand Down

0 comments on commit a02b8c2

Please sign in to comment.