Skip to content
This repository was archived by the owner on Oct 8, 2021. It is now read-only.

Commit d706aa9

Browse files
authored
Merge pull request #34 from JuliaGraphs/sbromberger/fix-33
fixes #33
2 parents 6fb3813 + 85f69d6 commit d706aa9

File tree

2 files changed

+88
-72
lines changed

2 files changed

+88
-72
lines changed

src/MetaGraphs.jl

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ has_vertex(g::AbstractMetaGraph, x...) = has_vertex(g.graph, x...)
7171
inneighbors(g::AbstractMetaGraph, v::Integer) = inneighbors(g.graph, v)
7272
outneighbors(g::AbstractMetaGraph, v::Integer) = fadj(g.graph, v)
7373

74-
issubset(g::T, h::T) where T<:AbstractMetaGraph = issubset(g.graph, h.graph)
74+
issubset(g::T, h::T) where T <: AbstractMetaGraph = issubset(g.graph, h.graph)
7575

7676
"""
7777
add_edge!(g, u, v, s, val)
@@ -113,7 +113,7 @@ end
113113
return true if the vertex has been added, false otherwise.
114114
"""
115115
add_vertex!(g::AbstractMetaGraph) = add_vertex!(g.graph)
116-
function add_vertex!(g::AbstractMetaGraph,d::Dict)
116+
function add_vertex!(g::AbstractMetaGraph, d::Dict)
117117
add_vertex!(g) || return false
118118
set_props!(g, nv(g), d)
119119
return true
@@ -140,28 +140,30 @@ function rem_vertex!(g::AbstractMetaGraph, v::Integer)
140140
for n in inneighbors(g, lastv)
141141
clear_props!(g, n, lastv)
142142
end
143-
144-
for n in outneighbors(g, v)
145-
clear_props!(g, v, n)
146-
end
147-
148-
for n in inneighbors(g, v)
149-
clear_props!(g, n, v)
143+
if v != lastv # ignore if we're removing the last vertex.
144+
for n in outneighbors(g, v)
145+
clear_props!(g, v, n)
146+
end
147+
for n in inneighbors(g, v)
148+
clear_props!(g, n, v)
149+
end
150150
end
151151
clear_props!(g, lastv)
152152
retval = rem_vertex!(g.graph, v)
153153
retval && set_props!(g, v, lastvprops)
154-
for n in outneighbors(g, v)
155-
set_props!(g, v, n, lasteoutprops[n])
156-
end
157-
158-
for n in inneighbors(g, v)
159-
set_props!(g, n, v, lasteinprops[n])
154+
if v != lastv # ignore if we're removing the last vertex.
155+
for n in outneighbors(g, v)
156+
set_props!(g, v, n, lasteoutprops[n])
157+
end
158+
159+
for n in inneighbors(g, v)
160+
set_props!(g, n, v, lasteinprops[n])
161+
end
160162
end
161163
return retval
162164
end
163165

164-
struct MetaWeights{T<:Integer,U<:Real} <: AbstractMatrix{U}
166+
struct MetaWeights{T <: Integer,U <: Real} <: AbstractMatrix{U}
165167
n::T
166168
weightfield::Symbol
167169
defaultweight::U
@@ -192,7 +194,7 @@ end
192194

193195
function getindex(g::AbstractMetaGraph, indx::Integer, prop::Symbol)
194196
haskey(g.metaindex, prop) || error("':$prop' is not an index")
195-
return props(g,indx)[prop]
197+
return props(g, indx)[prop]
196198
end
197199

198200
size(d::MetaWeights) = (d.n, d.n)
@@ -286,10 +288,10 @@ Will return false if vertex or edge does not exist, true otherwise
286288
set_prop!(g::AbstractMetaGraph, prop::Symbol, val) = set_props!(g, Dict(prop => val))
287289
set_prop!(g::AbstractMetaGraph, v::Integer, prop::Symbol, val) =
288290
if in(prop, g.indices)
289-
error("':$prop' is an indexing property, use `set_indexing_prop!()` instead")
290-
else
291-
set_props!(g, v, Dict(prop => val))
292-
end
291+
error("':$prop' is an indexing property, use `set_indexing_prop!()` instead")
292+
else
293+
set_props!(g, v, Dict(prop => val))
294+
end
293295
set_prop!(g::AbstractMetaGraph, e::SimpleEdge, prop::Symbol, val) = set_props!(g, e, Dict(prop => val))
294296

295297
set_prop!(g::AbstractMetaGraph{T}, u::Integer, v::Integer, prop::Symbol, val) where T = set_prop!(g, Edge(T(u), T(v)), prop, val)
@@ -316,10 +318,10 @@ rem_prop!(g::AbstractMetaGraph{T}, u::Integer, v::Integer, prop::Symbol) where T
316318
317319
Provides a default index value for a vertex if no value currently exists. The default is a string: "\$prop\$i" where `prop` is the property name and `i` is the vertex number. If some other vertex already has this name, a randomized string is generated (though the way it is generated is deterministic).
318320
"""
319-
function default_index_value(v::Integer, prop::Symbol, index_values::Set{Any}; exclude=nothing)
321+
function default_index_value(v::Integer, prop::Symbol, index_values::Set{Any}; exclude = nothing)
320322
val = string(prop) * string(v)
321323
if in(val, index_values) || val == exclude
322-
srand(v+hash(prop))
324+
srand(v + hash(prop))
323325
val = randstring()
324326
warn("'$(string(prop))$v' is already in index, setting ':$prop' for vertex $v to $val")
325327
end
@@ -335,16 +337,16 @@ are already set, each vertex must have unique values. Optionally, set the index
335337
`val` for vertex `v`. Any vertices without values will be set to a default
336338
("(prop)(v)").
337339
"""
338-
function set_indexing_prop!(g::AbstractMetaGraph, prop::Symbol; exclude=nothing)
340+
function set_indexing_prop!(g::AbstractMetaGraph, prop::Symbol; exclude = nothing)
339341
in(prop, g.indices) && return g.indices
340342
index_values = [g.vprops[v][prop] for v in keys(g.vprops) if haskey(g.vprops[v], prop)]
341343
length(index_values) != length(union(index_values)) && error("Cannot make $prop an index, duplicate values detected")
342344
index_values = Set(index_values)
343345

344-
g.metaindex[prop] = Dict{Any, Integer}()
346+
g.metaindex[prop] = Dict{Any,Integer}()
345347
for v in 1:size(g)[1]
346348
if !haskey(g.vprops, v) || !haskey(g.vprops[v], prop)
347-
val = default_index_value(v, prop, index_values, exclude=exclude)
349+
val = default_index_value(v, prop, index_values, exclude = exclude)
348350
set_prop!(g, v, prop, val)
349351
end
350352
g.metaindex[prop][g.vprops[v][prop]] = v
@@ -354,7 +356,7 @@ function set_indexing_prop!(g::AbstractMetaGraph, prop::Symbol; exclude=nothing)
354356
end
355357

356358
function set_indexing_prop!(g::AbstractMetaGraph, v::Integer, prop::Symbol, val::Any)
357-
!in(prop, g.indices) && set_indexing_prop!(g, prop, exclude=val)
359+
!in(prop, g.indices) && set_indexing_prop!(g, prop, exclude = val)
358360
(haskey(g.metaindex[prop], val) && g.vprops[v][prop] == val) && return g.indices
359361
haskey(g.metaindex[prop], val) && error("':$prop' index already contains $val")
360362

test/metagraphs.jl

Lines changed: 59 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,18 @@ importall MetaGraphs
1616
dgx = PathDiGraph(4)
1717

1818
mg = MetaGraph()
19-
@test add_vertex!(mg,:color,"red") && get_prop(mg,nv(mg),:color) == "red"
20-
@test add_vertex!(mg,Dict(:color=>"red",:prop2=>"prop2")) && props(mg,nv(mg)) == Dict(:color=>"red",:prop2=>"prop2")
21-
@test add_edge!(mg,1,2,:color,"blue") && get_prop(mg,1,2,:color) == "blue"
22-
@test add_vertex!(mg) && add_edge!(mg,1,3,Dict(:color => "red",:prop2 => "prop2")) && props(mg,1,3) == Dict(:color=>"red",:prop2=>"prop2")
19+
@test add_vertex!(mg, :color, "red") && get_prop(mg, nv(mg), :color) == "red"
20+
@test add_vertex!(mg, Dict(:color => "red", :prop2 => "prop2")) && props(mg, nv(mg)) == Dict(:color => "red", :prop2 => "prop2")
21+
@test add_edge!(mg, 1, 2, :color, "blue") && get_prop(mg, 1, 2, :color) == "blue"
22+
@test add_vertex!(mg) && add_edge!(mg, 1, 3, Dict(:color => "red", :prop2 => "prop2")) && props(mg, 1, 3) == Dict(:color => "red", :prop2 => "prop2")
2323

2424
for g in testgraphs(gx)
2525
mg = MetaGraph(g)
2626
g2 = SimpleGraph(mg)
2727
@test g2 == mg.graph
2828

29-
@test eltype(@inferred(MetaGraph{UInt8, Float16}(mg))) == UInt8
30-
@test weighttype(@inferred(MetaGraph{UInt8, Float16}(mg))) == Float16
29+
@test eltype(@inferred(MetaGraph{UInt8,Float16}(mg))) == UInt8
30+
@test weighttype(@inferred(MetaGraph{UInt8,Float16}(mg))) == Float16
3131

3232
@test @inferred(MetaGraphs.fadj(mg, 2)) == LightGraphs.SimpleGraphs.fadj(g, 2)
3333
@test @inferred(MetaGraphs.badj(mg, 2)) == LightGraphs.SimpleGraphs.badj(g, 2)
@@ -38,22 +38,22 @@ importall MetaGraphs
3838
@test @inferred(eltype(MetaGraph(g, 2.0))) == eltype(g)
3939
@test @inferred(eltype(MetaGraph(g, :cost))) == eltype(g)
4040
@test @inferred(eltype(MetaGraph(g, :cost, 2.0))) == eltype(g)
41-
@test @inferred(eltype(MetaGraph{UInt8, Float16}(g))) == UInt8
42-
@test @inferred(eltype(MetaGraph{UInt8, Float16}(g, :cost))) == UInt8
43-
@test @inferred(eltype(MetaGraph{UInt8, Float16}(g, 4))) == UInt8
41+
@test @inferred(eltype(MetaGraph{UInt8,Float16}(g))) == UInt8
42+
@test @inferred(eltype(MetaGraph{UInt8,Float16}(g, :cost))) == UInt8
43+
@test @inferred(eltype(MetaGraph{UInt8,Float16}(g, 4))) == UInt8
4444
@test @inferred(ne(mg)) == 3
4545
@test @inferred(nv(mg)) == 4
4646
@test @inferred(!is_directed(mg))
4747

4848
@test @inferred(vertices(mg)) == 1:4
49-
@test Edge(2,3) in edges(mg)
50-
@test @inferred(outneighbors(mg,2)) == inneighbors(mg,2) == neighbors(mg,2)
49+
@test Edge(2, 3) in edges(mg)
50+
@test @inferred(outneighbors(mg, 2)) == inneighbors(mg, 2) == neighbors(mg, 2)
5151
@test @inferred(has_edge(mg, 2, 3))
5252
@test @inferred(has_edge(mg, 3, 2))
5353

5454
mgc = copy(mg)
55-
@test @inferred(add_edge!(mgc, 4=>1)) && mgc == MetaGraph(CycleGraph(4))
56-
@test @inferred(has_edge(mgc, 4=>1)) && has_edge(mgc, 0x04=>0x01)
55+
@test @inferred(add_edge!(mgc, 4 => 1)) && mgc == MetaGraph(CycleGraph(4))
56+
@test @inferred(has_edge(mgc, 4 => 1)) && has_edge(mgc, 0x04 => 0x01)
5757
mgc = copy(mg)
5858
@test @inferred(add_edge!(mgc, (4, 1))) && mgc == MetaGraph(CycleGraph(4))
5959
@test @inferred(has_edge(mgc, (4, 1))) && has_edge(mgc, (0x04, 0x01))
@@ -69,11 +69,11 @@ importall MetaGraphs
6969
@test @inferred(rem_vertex!(mga, 2)) && ne(mga) == 1
7070
@test @inferred(!rem_vertex!(mga, 10))
7171

72-
@test @inferred(zero(mg)) == MetaGraph{eltype(mg), weighttype(mg)}()
72+
@test @inferred(zero(mg)) == MetaGraph{eltype(mg),weighttype(mg)}()
7373
@test @inferred(eltype(mg)) == eltype(outneighbors(mg, 1)) == eltype(nv(mg))
7474
T = @inferred(eltype(mg))
7575
U = @inferred(weighttype(mg))
76-
@test @inferred(nv(MetaGraph{T, U}(6))) == 6
76+
@test @inferred(nv(MetaGraph{T,U}(6))) == 6
7777

7878
end
7979

@@ -82,8 +82,8 @@ importall MetaGraphs
8282
g2 = SimpleDiGraph(mg)
8383
@test g2 == mg.graph
8484

85-
@test eltype(@inferred(MetaDiGraph{UInt8, Float16}(mg))) == UInt8
86-
@test weighttype(@inferred(MetaDiGraph{UInt8, Float16}(mg))) == Float16
85+
@test eltype(@inferred(MetaDiGraph{UInt8,Float16}(mg))) == UInt8
86+
@test weighttype(@inferred(MetaDiGraph{UInt8,Float16}(mg))) == Float16
8787

8888
@test @inferred(MetaGraphs.fadj(mg, 2)) == LightGraphs.SimpleGraphs.fadj(g, 2)
8989
@test @inferred(MetaGraphs.badj(mg, 2)) == LightGraphs.SimpleGraphs.badj(g, 2)
@@ -94,24 +94,24 @@ importall MetaGraphs
9494
@test @inferred(eltype(MetaDiGraph(g, 2.0))) == eltype(g)
9595
@test @inferred(eltype(MetaDiGraph(g, :cost))) == eltype(g)
9696
@test @inferred(eltype(MetaDiGraph(g, :cost, 2.0))) == eltype(g)
97-
@test @inferred(eltype(MetaDiGraph{UInt8, Float16}(g))) == UInt8
98-
@test @inferred(eltype(MetaDiGraph{UInt8, Float16}(g, :cost))) == UInt8
99-
@test @inferred(eltype(MetaDiGraph{UInt8, Float16}(g, 4))) == UInt8
97+
@test @inferred(eltype(MetaDiGraph{UInt8,Float16}(g))) == UInt8
98+
@test @inferred(eltype(MetaDiGraph{UInt8,Float16}(g, :cost))) == UInt8
99+
@test @inferred(eltype(MetaDiGraph{UInt8,Float16}(g, 4))) == UInt8
100100

101101
@test @inferred(ne(mg)) == 3
102102
@test @inferred(nv(mg)) == 4
103103
@test @inferred(is_directed(mg))
104104

105105
@test @inferred(vertices(mg)) == 1:4
106-
@test Edge(2,3) in edges(mg)
107-
@test @inferred(outneighbors(mg,2)) == [3]
108-
@test @inferred(inneighbors(mg,2)) == [1]
106+
@test Edge(2, 3) in edges(mg)
107+
@test @inferred(outneighbors(mg, 2)) == [3]
108+
@test @inferred(inneighbors(mg, 2)) == [1]
109109
@test @inferred(has_edge(mg, 2, 3))
110110
@test @inferred(!has_edge(mg, 3, 2))
111111

112112
mgc = copy(mg)
113-
@test @inferred(add_edge!(mgc, 4=>1)) && mgc == MetaDiGraph(CycleDiGraph(4))
114-
@test @inferred(has_edge(mgc, 4=>1)) && has_edge(mgc, 0x04=>0x01)
113+
@test @inferred(add_edge!(mgc, 4 => 1)) && mgc == MetaDiGraph(CycleDiGraph(4))
114+
@test @inferred(has_edge(mgc, 4 => 1)) && has_edge(mgc, 0x04 => 0x01)
115115
mgc = copy(mg)
116116
@test @inferred(add_edge!(mgc, (4, 1))) && mgc == MetaDiGraph(CycleDiGraph(4))
117117
@test @inferred(has_edge(mgc, (4, 1))) && has_edge(mgc, (0x04, 0x01))
@@ -127,11 +127,11 @@ importall MetaGraphs
127127
@test @inferred(rem_vertex!(mga, 2)) && ne(mga) == 1
128128
@test @inferred(!rem_vertex!(mga, 10))
129129

130-
@test @inferred(zero(mg)) == MetaDiGraph{eltype(mg), weighttype(mg)}()
130+
@test @inferred(zero(mg)) == MetaDiGraph{eltype(mg),weighttype(mg)}()
131131
@test @inferred(eltype(mg)) == eltype(outneighbors(mg, 1)) == eltype(nv(mg))
132132
T = @inferred(eltype(mg))
133133
U = @inferred(weighttype(mg))
134-
@test @inferred(nv(MetaDiGraph{T, U}(6))) == 6
134+
@test @inferred(nv(MetaDiGraph{T,U}(6))) == 6
135135
end
136136

137137
for gbig in [SimpleGraph(0xff), SimpleDiGraph(0xff)]
@@ -161,13 +161,13 @@ importall MetaGraphs
161161

162162
mg = MetaGraph(CompleteGraph(3), 3.0)
163163
@test enumerate_paths(dijkstra_shortest_paths(mg, 1), 3) == [1, 3]
164-
@test typeof(set_prop!(mg, 1, 2, :weight, 0.2)) == Dict{Symbol, Float64}
165-
@test typeof(set_prop!(mg, 2, 3, :weight, 1)) == Dict{Symbol, Int64}
164+
@test typeof(set_prop!(mg, 1, 2, :weight, 0.2)) == Dict{Symbol,Float64}
165+
@test typeof(set_prop!(mg, 2, 3, :weight, 1)) == Dict{Symbol,Int64}
166166
@test enumerate_paths(dijkstra_shortest_paths(mg, 1), 3) == [1, 2, 3]
167167

168-
@test typeof(set_prop!(mg, 1, :color, "blue")) == Dict{Symbol, String}
169-
@test typeof(set_prop!(mg, 1, :id, 0x5)) == Dict{Symbol, Any}
170-
@test typeof(set_prop!(mg, :name, "test graph")) == Dict{Symbol, Any}
168+
@test typeof(set_prop!(mg, 1, :color, "blue")) == Dict{Symbol,String}
169+
@test typeof(set_prop!(mg, 1, :id, 0x5)) == Dict{Symbol,Any}
170+
@test typeof(set_prop!(mg, :name, "test graph")) == Dict{Symbol,Any}
171171

172172

173173
@test length(props(mg)) == 1
@@ -198,13 +198,13 @@ importall MetaGraphs
198198
mg = MetaDiGraph(PathDiGraph(3), 3.0)
199199
add_edge!(mg, 1, 3)
200200
@test enumerate_paths(dijkstra_shortest_paths(mg, 1), 3) == [1, 3]
201-
@test typeof(set_prop!(mg, 1, 2, :weight, 0.2)) == Dict{Symbol, Float64}
202-
@test typeof(set_prop!(mg, 2, 3, :weight, 1)) == Dict{Symbol, Int64}
201+
@test typeof(set_prop!(mg, 1, 2, :weight, 0.2)) == Dict{Symbol,Float64}
202+
@test typeof(set_prop!(mg, 2, 3, :weight, 1)) == Dict{Symbol,Int64}
203203
@test enumerate_paths(dijkstra_shortest_paths(mg, 1), 3) == [1, 2, 3]
204204

205-
@test typeof(set_prop!(mg, 1, :color, "blue")) == Dict{Symbol, String}
206-
@test typeof(set_prop!(mg, 1, :id, 0x5)) == Dict{Symbol, Any}
207-
@test typeof(set_prop!(mg, :name, "test graph")) == Dict{Symbol, Any}
205+
@test typeof(set_prop!(mg, 1, :color, "blue")) == Dict{Symbol,String}
206+
@test typeof(set_prop!(mg, 1, :id, 0x5)) == Dict{Symbol,Any}
207+
@test typeof(set_prop!(mg, :name, "test graph")) == Dict{Symbol,Any}
208208

209209

210210
@test length(props(mg)) == 1
@@ -249,10 +249,10 @@ importall MetaGraphs
249249
@test weightfield!(mg, :weight) == :weight
250250
@test enumerate_paths(dijkstra_shortest_paths(mg, 1), 3) == [1, 2, 3]
251251

252-
@test length(set_props!(mg, 1, 2, Dict(:color=>:blue, :action=>"knows"))) == 3
252+
@test length(set_props!(mg, 1, 2, Dict(:color => :blue, :action => "knows"))) == 3
253253
@test rem_edge!(mg, 1, 2)
254254
@test length(props(mg, 1, 2)) == 0
255-
@test length(set_props!(mg, Dict(:name=>"testgraph", :type=>"undirected"))) == 2
255+
@test length(set_props!(mg, Dict(:name => "testgraph", :type => "undirected"))) == 2
256256

257257
mg = MetaGraph(CompleteGraph(3), 3.0)
258258
set_prop!(mg, 1, :color, "blue")
@@ -327,6 +327,19 @@ importall MetaGraphs
327327
@test length(mga.eprops) == 1 # should only be edge 3=>2
328328
@test props(mga, 3, 2)[:name] == "3, 4"
329329

330+
# test for #33
331+
mga = MetaGraph(PathGraph(4))
332+
set_prop!(mga, 1, 2, :name, "1, 2")
333+
set_prop!(mga, 2, 3, :name, "2, 3")
334+
set_prop!(mga, 3, 4, :name, "3, 4")
335+
set_prop!(mga, 3, :v, 3)
336+
set_prop!(mga, 4, :v, 4)
337+
@test rem_vertex!(mga, nv(mga))
338+
@test has_prop(mga, 2, 3, :name)
339+
@test !has_prop(mga, 3, 4, :name)
340+
@test !has_prop(mga, 4, :v)
341+
@test has_prop(mga, 3, :v)
342+
330343

331344

332345

@@ -342,8 +355,8 @@ end
342355
end
343356

344357
for i in 1:100
345-
set_prop!(G, i, :not_unique, "$(i%5)")
346-
set_prop!(dG, i, :not_unique, "$(i%5)")
358+
set_prop!(G, i, :not_unique, "$(i % 5)")
359+
set_prop!(dG, i, :not_unique, "$(i % 5)")
347360
end
348361

349362
@test set_indexing_prop!(G, :name) == Set{Symbol}([:name])
@@ -358,9 +371,10 @@ end
358371
@test_throws ErrorException set_indexing_prop!(dG, 4, :name, "dgnode_3")
359372
@test_throws ErrorException set_prop!(G, 3, :name, "name3")
360373
@test_throws ErrorException set_prop!(dG, 3, :name, "name3")
361-
@test_throws ErrorException set_props!(G, 5, Dict(:name=>"name", :other_name=>"something"))
362-
@test_throws ErrorException set_props!(dG, 5, Dict(:name=>"name", :other_name=>"something"))
374+
@test_throws ErrorException set_props!(G, 5, Dict(:name => "name", :other_name => "something"))
375+
@test_throws ErrorException set_props!(dG, 5, Dict(:name => "name", :other_name => "something"))
363376

377+
info("Ignore \"'foo1' is already in index\" warnings")
364378
set_indexing_prop!(G, 50, :name, "another name")
365379
set_indexing_prop!(G, 50, :name, "another name")
366380

@@ -376,8 +390,8 @@ end
376390
@test G[12, :foo] == "foo12"
377391
@test G["bar", :foo] == 42
378392
@test G[42, :foo] == "bar"
379-
@test isa(G[:foo], Dict{Any, Integer})
380-
@test isa(dG[:foo], Dict{Any, Integer})
393+
@test isa(G[:foo], Dict{Any,Integer})
394+
@test isa(dG[:foo], Dict{Any,Integer})
381395

382396

383397
@test dG["foo30", :foo] == 30

0 commit comments

Comments
 (0)