Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested enumeration container #213

Merged
merged 6 commits into from
Dec 10, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
version = "0.4.3"

[[BinDeps]]
deps = ["Compat", "Libdl", "SHA", "URIParser"]
git-tree-sha1 = "12093ca6cdd0ee547c39b1870e0c9c3f154d9ca9"
deps = ["Libdl", "Pkg", "SHA", "URIParser", "Unicode"]
git-tree-sha1 = "66158ad56b4bf6cc8413b37d0b7bc52402682764"
uuid = "9e28174c-4ba2-5203-b857-d8d62c4213ee"
version = "0.8.10"
version = "1.0.0"

[[BinaryProvider]]
deps = ["Libdl", "SHA"]
Expand All @@ -37,7 +37,7 @@ version = "0.5.1"
deps = ["BlockDecomposition", "DelimitedFiles", "JuMP"]
git-tree-sha1 = "7b06d67b3883ff9d9ec7c655cc288948b9894fc0"
repo-rev = "master"
repo-url = "https://github.com/atoptima/ColunaDemos.jl.git"
repo-url = "git@github.com:atoptima/ColunaDemos.jl.git"
uuid = "a54e61d4-7723-11e9-2469-af255fcaa246"
version = "0.1.0"

Expand Down Expand Up @@ -85,9 +85,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"

[[ForwardDiff]]
deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "NaNMath", "Random", "SpecialFunctions", "StaticArrays"]
git-tree-sha1 = "4407e7b76999eca2646abdb68203bd4302476168"
git-tree-sha1 = "da46ac97b17793eba44ff366dc6cb70f1238a738"
uuid = "f6369f11-7733-5829-9624-2563aa707210"
version = "0.10.6"
version = "0.10.7"

[[InteractiveUtils]]
deps = ["Markdown"]
Expand Down Expand Up @@ -152,6 +152,12 @@ version = "0.3.10"
deps = ["Dates", "LibGit2", "Markdown", "Printf", "REPL", "Random", "SHA", "UUIDs"]
uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"

[[Primes]]
deps = ["Test"]
git-tree-sha1 = "ff1a2323cb468ec5f201838fcbe3c232266b1f95"
uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae"
version = "0.4.0"

[[Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Expand Down
1 change: 1 addition & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
Logging = "56ddb016-857b-54e1-b83d-db4d58db5568"
MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Primes = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
TimerOutputs = "a759f4b9-e2f1-59dc-863e-4aeb61b1ea8f"
Expand Down
2 changes: 2 additions & 0 deletions src/Coluna.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import DataStructures
import BlockDecomposition
import Distributed
import TimerOutputs
import Primes

using Logging
using Printf
Expand Down Expand Up @@ -35,6 +36,7 @@ include("varconstr.jl")

include("containers/elements.jl")
include("containers/members.jl")
include("containers/nestedenum.jl")

include("manager.jl")
include("filters.jl")
Expand Down
89 changes: 89 additions & 0 deletions src/containers/nestedenum.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
abstract type NestedEnum end

import Base.<=

function <=(a::T, b::T) where {T <: NestedEnum}
return a.id % b.id == 0
end

function _store!(expr::Symbol, i, names, parent_pos, leaves, primes)
names[i] = expr
parent_pos[i] = 0 # No parent
leaves[i] = true
primes[i] = Primes.prime(i)
return
end

function _store!(expr::Expr, i, names, parent_pos, leaves, primes)
expr.head == :call || error("Syntax.")
expr.args[1] == :(<=) || error("Syntax error : Child <= Parent ")
i > 1 || error("First element cannot have a parent.")

name = expr.args[2]
parent_name = expr.args[3]

r = findall(n -> n == parent_name, names[1:i-1])
length(r) == 0 && error("Unknow parent $(parent_name).")
length(r) > 1 && error("$parent_name registered more than once.")
parent_pos[i] = r[1]
names[i] = name
leaves[i] = true
primes[i] = Primes.prime(i)
return
end

function _compute_values!(values, parent_pos, primes)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a small comment to this function?

for i in 1:length(parent_pos)
factor = 1.0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it not an Int?

j = parent_pos[i]
if j != 0
factor = values[j]
end
values[i] = primes[i] * factor
end
return
end

"""
@nestedenum begin
Root
ChildA <= Root
GrandChildA1 <= ChildA
GrandChildA2 <= ChildA
ChildB <= Root
ChildC <= Root
end

Create a nested enumeration with name `Root` and elements `ChildA`,
`GrandChildA1`, `GrandChildA2`, `ChildB`, and `ChildC`.
The operator `<=` indicates the parent of the element.
In this example, `Root` is the parent of `ChildA`, `ChildB`, and `ChildC`;
`ChildA` is the parent of `GrandChildA1` and `GrandChildA2`.
"""
macro nestedenum(expr)
Base.remove_linenums!(expr)

expr.head == :block || error("Block expression expected.")

len = length(expr.args)
names = Array{Symbol}(undef, len)
parent_pos = zeros(Int, len)
leaves = falses(len)
primes = zeros(Int, len)
values = zeros(UInt32, len)

name_values = Dict{Symbol, Int}()
for (i, arg) in enumerate(expr.args)
_store!(arg, i, names, parent_pos, leaves, primes)
end

_compute_values!(values, parent_pos, primes)

root_name = names[1]
enum_expr = Expr(:block, :(struct $root_name <: Coluna.NestedEnum id::UInt end))

for i in 2:len
push!(enum_expr.args, :($(names[i]) = $(root_name)(UInt($(values[i])))))
end
return esc(enum_expr)
end
2 changes: 1 addition & 1 deletion test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#using Revise
import Coluna
using Coluna

using Test, GLPK, ColunaDemos, JuMP, BlockDecomposition

Expand Down
32 changes: 32 additions & 0 deletions test/unit/containers/nestedenum.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
Coluna.@nestedenum begin
VarConstrDuty
A <= VarConstrDuty
A1 <= A
A2 <= A
A3 <= A
B <= VarConstrDuty
B1 <= B
B2 <= B
B3 <= B
B3A <= B3
B3B <= B3
B3C <= B3
C <= VarConstrDuty
D <= VarConstrDuty
D1 <= D
D1A <= D1
D1B <= D1
D2 <= D
E <= VarConstrDuty
end

function nestedenum_unit()
@test <=(A1, A)
@test A1 <= A

@test !<=(A, B)
@test !(A <= B)

@test <=(B3A, B)
@test B3A <= B
end
5 changes: 5 additions & 0 deletions test/unit/unit_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ include("types.jl")
include("algorithms/algorithm.jl")
include("strategies/strategy.jl")
include("containers/members.jl")
include("containers/nestedenum.jl")
# include("parameters.jl")
include("counters.jl")
include("vcids.jl")
Expand Down Expand Up @@ -36,6 +37,10 @@ include("incumbents.jl")


function unit_tests()
@testset "Containers" begin
nestedenum_unit()
end

@testset "types.jl" begin
types_unit_tests()
end
Expand Down