-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathdescription.jl
147 lines (120 loc) · 3.2 KB
/
description.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
"""
DescVarArg is a Vararg of symbols. `DescVarArg` is a type alias for a Vararg of symbols.
```@example
julia> const DescVarArg = Vararg{Symbol}
```
See also: [`Description`](@ref).
"""
const DescVarArg = Vararg{Symbol}
"""
A description is a tuple of symbols. `Description` is a type alias for a tuple of symbols.
```@example
julia> const Description = Tuple{DescVarArg}
```
See also: [`DescVarArg`](@ref).
# Example
[`Base.show`](@ref) is overloaded for descriptions, that is tuple of descriptions are printed as follows:
```@example
julia> display( ( (:a, :b), (:b, :c) ) )
(:a, :b)
(:b, :c)
```
"""
const Description = Tuple{DescVarArg}
"""
$(TYPEDSIGNATURES)
Print a tuple of descriptions.
# Example
```@example
julia> display( ( (:a, :b), (:b, :c) ) )
(:a, :b)
(:b, :c)
```
"""
function Base.show(io::IO, ::MIME"text/plain", descriptions::Tuple{Vararg{Description}})
N = size(descriptions, 1)
for i in range(1, N)
description = descriptions[i]
i < N ? print(io, "$description\n") : print(io, "$description")
end
end
"""
$(TYPEDSIGNATURES)
Return a tuple containing only the description `y`.
# Example
```@example
julia> descriptions = ()
julia> descriptions = add(descriptions, (:a,))
(:a,)
julia> print(descriptions)
((:a,),)
julia> descriptions[1]
(:a,)
```
"""
add(x::Tuple{}, y::Description)::Tuple{Vararg{Description}} = (y,)
"""
$(TYPEDSIGNATURES)
Concatenate the description `y` to the tuple of descriptions `x` if `x` does not contain `y`
and return the new tuple of descriptions. Throw an error if the description `y` is already contained in `x`.
# Example
```@example
julia> descriptions = ()
julia> descriptions = add(descriptions, (:a,))
(:a,)
julia> descriptions = add(descriptions, (:b,))
(:a,)
(:b,)
julia> descriptions = add(descriptions, (:b,))
ERROR: IncorrectArgument: the description (:b,) is already in ((:a,), (:b,))
```
"""
function add(x::Tuple{Vararg{Description}}, y::Description)::Tuple{Vararg{Description}}
if y ∈ x
throw(IncorrectArgument("the description $y is already in $x"))
else
return (x..., y)
end
end
"""
$(TYPEDSIGNATURES)
Return a complete description from an incomplete description `desc` and
a list of complete descriptions `desc_list`. If several complete descriptions are possible,
then the first one is returned.
# Example
```@example
julia> desc_list = ((:a, :b), (:b, :c), (:a, :c))
(:a, :b)
(:b, :c)
(:a, :c)
julia> getFullDescription((:a,), desc_list)
(:a, :b)
```
"""
function getFullDescription(
desc::Description, desc_list::Tuple{Vararg{Description}}
)::Description
n = size(desc_list, 1)
table = zeros(Int8, n, 2)
for i in range(1, n)
table[i, 1] = size(desc ∩ desc_list[i], 1)
table[i, 2] = desc ⊆ desc_list[i] ? 1 : 0
end
if maximum(table[:, 2]) == 0
throw(AmbiguousDescription(desc))
end
# argmax : Return the index or key of the maximal element in a collection.
return desc_list[argmax(table[:, 1])]
end
"""
$(TYPEDSIGNATURES)
Return the difference between the description `x` and the description `y`.
# Example
```@example
julia> remove((:a, :b), (:a,))
(:b,)
```
"""
function remove(x::Description, y::Description)::Description
return Tuple(setdiff(x, y))
end