blegat / HybridSystems.jl

Compare 795aee1 ... +0 ... 50adbd7

No flags found

Use flags to group coverage reports by test type, project and/or folders.
Then setup custom commit statuses and notifications for each flag.

e.g., #unittest #integration

#production #enterprise

#frontend #backend

Learn more about Codecov Flags here.


@@ -4,27 +4,27 @@
Loading
4 4
using MappedArrays: ReadonlyMappedArray
5 5
6 6
"""
7 -
    LightAutomaton{GT, ET} <: AbstractAutomaton
7 +
    GraphAutomaton{GT, ET} <: AbstractAutomaton
8 8
9 9
A hybrid automaton that uses the `Graphs` backend. See the constructor
10 -
[`LightAutomaton(::Int)`](@ref).
10 +
[`GraphAutomaton(::Int)`](@ref).
11 11
12 12
###  Fields
13 13
14 14
- `G` -- graph of type `GT` whose vertices determine the states
15 15
- `Σ` -- dictionary mapping the edges to their labels
16 16
"""
17 -
mutable struct LightAutomaton{GT, ET} <: AbstractAutomaton
17 +
mutable struct GraphAutomaton{GT, ET} <: AbstractAutomaton
18 18
    G::GT
19 19
    Σ::Dict{ET, Dict{Int, Int}}
20 20
    next_id::Int
21 21
    nt::Int
22 22
end
23 23
24 24
"""
25 -
    LightAutomaton(n::Int)
25 +
    GraphAutomaton(n::Int)
26 26
27 -
Creates a `LightAutomaton` with `n` states 1, 2, ..., `n`.
27 +
Creates a `GraphAutomaton` with `n` states 1, 2, ..., `n`.
28 28
The automaton is initialized without any transitions,
29 29
use [`add_transition!`](@ref) to add transitions.
30 30
@@ -34,95 +34,95 @@
Loading
34 34
from 1 to 2 with label 2 and transition from 2 to 1 with label 3, do the
35 35
following:
36 36
```jldoctest
37 -
julia> a = LightAutomaton(2);
37 +
julia> a = GraphAutomaton(2);
38 38
39 39
julia> add_transition!(a, 1, 1, 1) # Add a self-loop of label 1 for state 1
40 -
HybridSystems.LightTransition{Graphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 1 => 1, 1)
40 +
HybridSystems.GraphTransition{Graphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 1 => 1, 1)
41 41
42 42
julia> add_transition!(a, 2, 2, 1) # Add a self-loop of label 1 for state 2
43 -
HybridSystems.LightTransition{Graphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 2 => 2, 2)
43 +
HybridSystems.GraphTransition{Graphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 2 => 2, 2)
44 44
45 45
julia> add_transition!(a, 1, 2, 2) # Add a transition from state 1 to state 2 with label 2
46 -
HybridSystems.LightTransition{Graphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 1 => 2, 3)
46 +
HybridSystems.GraphTransition{Graphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 1 => 2, 3)
47 47
48 48
julia> add_transition!(a, 2, 1, 3) # Add a transition from state 2 to state 1 with label 3
49 -
HybridSystems.LightTransition{Graphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 2 => 1, 4)
49 +
HybridSystems.GraphTransition{Graphs.SimpleGraphs.SimpleEdge{Int64}}(Edge 2 => 1, 4)
50 50
```
51 51
"""
52 -
function LightAutomaton(n::Int)
52 +
function GraphAutomaton(n::Int)
53 53
    G = Graphs.DiGraph(n)
54 54
    Σ = Dict{Graphs.edgetype(G), Dict{Int, Int}}()
55 -
    LightAutomaton(G, Σ, 0, 0)
55 +
    GraphAutomaton(G, Σ, 0, 0)
56 56
end
57 57
58 -
struct LightTransition{ET} <: AbstractTransition
58 +
struct GraphTransition{ET} <: AbstractTransition
59 59
    edge::ET
60 60
    id::Int
61 61
end
62 62
63 63
"""
64 -
    struct LightTransitionIterator{GT, ET, VT}
65 -
        automaton::LightAutomaton{GT, ET}
64 +
    struct GraphTransitionIterator{GT, ET, VT}
65 +
        automaton::GraphAutomaton{GT, ET}
66 66
        edge_iterator::VT
67 67
    end
68 68
69 69
Iterate over the transitions of `automaton` by iterating over the edges `edge`
70 70
of `edge_iterator` and the ids `id` of `automaton.Σ[edge]` for each one. Its
71 -
elements are `LightTransition(edge, id)`.
71 +
elements are `GraphTransition(edge, id)`.
72 72
"""
73 -
struct LightTransitionIterator{GT, ET, VT}
74 -
    automaton::LightAutomaton{GT, ET}
73 +
struct GraphTransitionIterator{GT, ET, VT}
74 +
    automaton::GraphAutomaton{GT, ET}
75 75
    edge_iterator::VT
76 76
end
77 -
Base.eltype(::LightTransitionIterator{GT, ET}) where {GT, ET} = LightTransition{ET}
78 -
function Base.length(tit::LightTransitionIterator)
77 +
Base.eltype(::GraphTransitionIterator{GT, ET}) where {GT, ET} = GraphTransition{ET}
78 +
function Base.length(tit::GraphTransitionIterator)
79 79
    eit = tit.edge_iterator
80 80
    # empty iterator must be handled separately (see #29)
81 81
    return isempty(eit) ? 0 : sum(edge -> length(tit.automaton.Σ[edge]), eit)
82 82
end
83 -
function new_id_iterate(tit::LightTransitionIterator, edge, edge_state, ids, ::Nothing)
83 +
function new_id_iterate(tit::GraphTransitionIterator, edge, edge_state, ids, ::Nothing)
84 84
    return new_edge_iterate(tit, iterate(tit.edge_iterator, edge_state))
85 85
end
86 -
function new_id_iterate(tit::LightTransitionIterator, edge, edge_state, ids, id_item_state)
86 +
function new_id_iterate(tit::GraphTransitionIterator, edge, edge_state, ids, id_item_state)
87 87
    idσ, id_state = id_item_state
88 -
    return LightTransition(edge, idσ[1]), (edge, edge_state, ids, id_state)
88 +
    return GraphTransition(edge, idσ[1]), (edge, edge_state, ids, id_state)
89 89
end
90 -
new_edge_iterate(::LightTransitionIterator, ::Nothing) = nothing
91 -
function new_edge_iterate(tit::LightTransitionIterator, edge_item_state)
90 +
new_edge_iterate(::GraphTransitionIterator, ::Nothing) = nothing
91 +
function new_edge_iterate(tit::GraphTransitionIterator, edge_item_state)
92 92
    edge, edge_state = edge_item_state
93 93
    ids = tit.automaton.Σ[edge]
94 94
    return new_id_iterate(tit, edge, edge_state, ids, iterate(ids))
95 95
end
96 -
function Base.iterate(tit::LightTransitionIterator)
96 +
function Base.iterate(tit::GraphTransitionIterator)
97 97
    return new_edge_iterate(tit, iterate(tit.edge_iterator))
98 98
end
99 -
function Base.iterate(tit::LightTransitionIterator, edge_id_state)
99 +
function Base.iterate(tit::GraphTransitionIterator, edge_id_state)
100 100
    edge, edge_state, ids, id_state = edge_id_state
101 101
    return new_id_iterate(tit, edge, edge_state, ids, iterate(ids, id_state))
102 102
end
103 103
104 -
states(A::LightAutomaton) = Graphs.vertices(A.G)
105 -
nstates(A::LightAutomaton) = Graphs.nv(A.G)
104 +
states(A::GraphAutomaton) = Graphs.vertices(A.G)
105 +
nstates(A::GraphAutomaton) = Graphs.nv(A.G)
106 106
107 -
transitiontype(A::LightAutomaton) = LightTransition{Graphs.edgetype(A.G)}
108 -
function transitions(A::LightAutomaton)
109 -
    return LightTransitionIterator(A, Graphs.edges(A.G))
107 +
transitiontype(A::GraphAutomaton) = GraphTransition{Graphs.edgetype(A.G)}
108 +
function transitions(A::GraphAutomaton)
109 +
    return GraphTransitionIterator(A, Graphs.edges(A.G))
110 110
end
111 -
ntransitions(A::LightAutomaton) = A.nt
111 +
ntransitions(A::GraphAutomaton) = A.nt
112 112
113 -
function edge_object(A::LightAutomaton, q, r)
113 +
function edge_object(A::GraphAutomaton, q, r)
114 114
    @assert 1 <= q <= nstates(A)
115 115
    @assert 1 <= r <= nstates(A)
116 116
    return Graphs.Edge(q, r)
117 117
end
118 118
119 119
# return transitions with source `q` and target `r`
120 -
function transitions(A::LightAutomaton{GT, ET}, q, r) where {GT, ET}
120 +
function transitions(A::GraphAutomaton{GT, ET}, q, r) where {GT, ET}
121 121
    e = edge_object(A, q, r)
122 -
    LightTransitionIterator(A, Fill(e, Graphs.has_edge(A.G, e) ? 1 : 0))
122 +
    GraphTransitionIterator(A, Fill(e, Graphs.has_edge(A.G, e) ? 1 : 0))
123 123
end
124 124
125 -
function add_transition!(A::LightAutomaton, q, r, σ)
125 +
function add_transition!(A::GraphAutomaton, q, r, σ)
126 126
    edge = edge_object(A, q, r)
127 127
    A.next_id += 1
128 128
    A.nt += 1
@@ -137,15 +137,15 @@
Loading
137 137
        Graphs.add_edge!(A.G, edge)
138 138
        A.Σ[edge] = ids
139 139
    end
140 -
    return LightTransition(edge, id)
140 +
    return GraphTransition(edge, id)
141 141
end
142 -
function has_transition(A::LightAutomaton, q, r)
142 +
function has_transition(A::GraphAutomaton, q, r)
143 143
    return Graphs.has_edge(A.G, edge_object(A, q, r))
144 144
end
145 -
function has_transition(A::LightAutomaton, t::LightTransition)
145 +
function has_transition(A::GraphAutomaton, t::GraphTransition)
146 146
    return Graphs.has_edge(A.G, t.edge) && haskey(A.Σ[t.edge], t.id)
147 147
end
148 -
function rem_transition!(A::LightAutomaton, t::LightTransition)
148 +
function rem_transition!(A::GraphAutomaton, t::GraphTransition)
149 149
    ids = A.Σ[t.edge]
150 150
    delete!(ids, t.id)
151 151
    A.nt -= 1
@@ -155,7 +155,7 @@
Loading
155 155
    end
156 156
end
157 157
158 -
function rem_state!(A::LightAutomaton, st)
158 +
function rem_state!(A::GraphAutomaton, st)
159 159
    # We need to collect as we delete them in the loop
160 160
    for t in collect(in_transitions(A, st))
161 161
        rem_transition!(A, t)
@@ -166,62 +166,62 @@
Loading
166 166
    return Graphs.rem_vertex!(A.G, st)
167 167
end
168 168
169 -
function add_state!(A::LightAutomaton)
169 +
function add_state!(A::GraphAutomaton)
170 170
    return Graphs.add_vertex!(A.G)
171 171
end
172 172
173 -
source(::LightAutomaton, t::LightTransition) = t.edge.src
174 -
event(A::LightAutomaton, t::LightTransition) = A.Σ[t.edge][t.id]
175 -
target(::LightAutomaton, t::LightTransition) = t.edge.dst
173 +
source(::GraphAutomaton, t::GraphTransition) = t.edge.src
174 +
event(A::GraphAutomaton, t::GraphTransition) = A.Σ[t.edge][t.id]
175 +
target(::GraphAutomaton, t::GraphTransition) = t.edge.dst
176 176
177 -
function in_transitions(A::LightAutomaton{GT, ET}, s) where {GT, ET}
177 +
function in_transitions(A::GraphAutomaton{GT, ET}, s) where {GT, ET}
178 178
    f(src) = edge_object(A, src, s)
179 179
    inneigh = Graphs.inneighbors(A.G, s)
180 180
    edges = ReadonlyMappedArray{ET, 1, typeof(inneigh), typeof(f)}(f, inneigh)
181 -
    LightTransitionIterator(A, edges)
181 +
    GraphTransitionIterator(A, edges)
182 182
end
183 -
function out_transitions(A::LightAutomaton{GT, ET}, s) where {GT, ET}
183 +
function out_transitions(A::GraphAutomaton{GT, ET}, s) where {GT, ET}
184 184
    f(dst) = edge_object(A, s, dst)
185 185
    outneigh = Graphs.outneighbors(A.G, s)
186 186
    edges = ReadonlyMappedArray{ET, 1, typeof(outneigh), typeof(f)}(f, outneigh)
187 -
    LightTransitionIterator(A, edges)
187 +
    GraphTransitionIterator(A, edges)
188 188
end
189 189
190 -
struct LightStateProperty{GT, ET, T} <: StateProperty{T}
191 -
    automaton::LightAutomaton{GT, ET}
190 +
struct GraphStateProperty{GT, ET, T} <: StateProperty{T}
191 +
    automaton::GraphAutomaton{GT, ET}
192 192
    value::Vector{T}
193 193
end
194 -
function state_property_type(::Type{LightAutomaton{GT, ET}},
194 +
function state_property_type(::Type{GraphAutomaton{GT, ET}},
195 195
                             T::Type) where {GT, ET}
196 -
    return LightStateProperty{GT, ET, T}
196 +
    return GraphStateProperty{GT, ET, T}
197 197
end
198 -
function state_property(automaton::LightAutomaton, T::Type)
199 -
    return LightStateProperty(automaton, Vector{T}(undef, nstates(automaton)))
198 +
function state_property(automaton::GraphAutomaton, T::Type)
199 +
    return GraphStateProperty(automaton, Vector{T}(undef, nstates(automaton)))
200 200
end
201 -
function Base.getindex(p::LightStateProperty,
201 +
function Base.getindex(p::GraphStateProperty,
202 202
                       s::Int)
203 203
    p.value[s]
204 204
end
205 -
function Base.setindex!(p::LightStateProperty, value,
205 +
function Base.setindex!(p::GraphStateProperty, value,
206 206
                        s::Int)
207 207
    p.value[s] = value
208 208
end
209 209
210 -
struct LightTransitionProperty{GT, ET, T} <: TransitionProperty{T}
211 -
    automaton::LightAutomaton{GT, ET}
210 +
struct GraphTransitionProperty{GT, ET, T} <: TransitionProperty{T}
211 +
    automaton::GraphAutomaton{GT, ET}
212 212
    value::Vector{T}
213 213
end
214 -
function transition_property_type(::Type{LightAutomaton{GT, ET}}, T::Type) where {GT, ET}
215 -
    return LightTransitionProperty{GT, ET, T}
214 +
function transition_property_type(::Type{GraphAutomaton{GT, ET}}, T::Type) where {GT, ET}
215 +
    return GraphTransitionProperty{GT, ET, T}
216 216
end
217 -
function transition_property(automaton::LightAutomaton, T::Type)
218 -
    return LightTransitionProperty(automaton, Vector{T}(undef, automaton.next_id))
217 +
function transition_property(automaton::GraphAutomaton, T::Type)
218 +
    return GraphTransitionProperty(automaton, Vector{T}(undef, automaton.next_id))
219 219
end
220 -
function Base.getindex(p::LightTransitionProperty,
221 -
                       t::LightTransition)
220 +
function Base.getindex(p::GraphTransitionProperty,
221 +
                       t::GraphTransition)
222 222
    p.value[t.id]
223 223
end
224 -
function Base.setindex!(p::LightTransitionProperty, value,
225 -
                        t::LightTransition)
224 +
function Base.setindex!(p::GraphTransitionProperty, value,
225 +
                        t::GraphTransition)
226 226
    p.value[t.id] = value
227 227
end

@@ -55,7 +55,7 @@
Loading
55 55
    HybridSystem(G, modes, rm, sw, Dict{Symbol, Any}(kws))
56 56
end
57 57
function discreteswitchedsystem(A::AbstractVector{<:AbstractMatrix}, S::AbstractVector; kws...)
58 -
    G = LightAutomaton(length(A))
58 +
    G = GraphAutomaton(length(A))
59 59
    for σ in 1:length(A)
60 60
        for σnext in 1:length(A)
61 61
            add_transition!(G, σ, σnext, σ)

@@ -1,4 +1,4 @@
Loading
1 -
export LightAutomaton, AbstractAutomaton, OneStateAutomaton
1 +
export GraphAutomaton, AbstractAutomaton, OneStateAutomaton
2 2
export states, modes, nstates, nmodes, transitions, ntransitions
3 3
export source, event, symbol, target, transitiontype
4 4
export add_transition!, has_transition, rem_transition!, rem_state!, add_state!

Everything is accounted for!

No changes detected that need to be reviewed.
What changes does Codecov check for?
Lines, not adjusted in diff, that have changed coverage data.
Files that introduced coverage data that had none before.
Files that have missing coverage data that once were tracked.
Files Coverage
Project Totals (7 files) 94.94%
Loading