@@ -27,48 +27,137 @@ Create an `ExploreSettings` object to configure the exploration of a search spac
27
27
function ExploreSettings (
28
28
domains;
29
29
complete_search_limit = 10 ^ 6 ,
30
- max_samplings = sum (domain_size, domains),
30
+ max_samplings = sum (domain_size, domains; init = 0 ),
31
31
search = :flexible ,
32
32
solutions_limit = floor (Int, sqrt (max_samplings)),
33
33
)
34
34
return ExploreSettings (complete_search_limit, max_samplings, search, solutions_limit)
35
35
end
36
36
37
+ struct ExplorerState{T}
38
+ best:: Vector{T}
39
+ solutions:: Set{Vector{T}}
40
+ non_solutions:: Set{Vector{T}}
41
+
42
+ ExplorerState {T} () where {T} = new {T} ([], Set {Vector{T}} (), Set {Vector{T}} ())
43
+ end
44
+
45
+ ExplorerState (domains) = ExplorerState {Union{map(eltype, domains)...}} ()
46
+
47
+ mutable struct Explorer{F1<: Function ,D<: AbstractDomain ,F2<: Union{Function,Nothing} ,T}
48
+ concepts:: Dict{Int,Tuple{F1,Vector{Int}}}
49
+ domains:: Dict{Int,D}
50
+ objective:: F2
51
+ settings:: ExploreSettings
52
+ state:: ExplorerState{T}
53
+
54
+ function Explorer (
55
+ concepts,
56
+ domains,
57
+ objective = nothing ;
58
+ settings = ExploreSettings (domains),
59
+ )
60
+ F1 = isempty (concepts) ? Function : Union{map (c -> typeof (c[1 ]), concepts)... }
61
+ D = isempty (domains) ? AbstractDomain : Union{map (typeof, domains)... }
62
+ F2 = typeof (objective)
63
+ T = isempty (domains) ? Real : Union{map (eltype, domains)... }
64
+ d_c = Dict (enumerate (concepts))
65
+ d_d = Dict (enumerate (domains))
66
+ return new {F1,D,F2,T} (d_c, d_d, objective, settings, ExplorerState {T} ())
67
+ end
68
+ end
69
+
70
+ function Explorer ()
71
+ concepts = Vector {Tuple{Function,Vector{Int}}} ()
72
+ domains = Vector {AbstractDomain} ()
73
+ objective = nothing
74
+ settings = ExploreSettings (domains)
75
+ return Explorer (concepts, domains, objective; settings)
76
+ end
77
+
78
+ function Base. push! (explorer:: Explorer , concept:: Tuple{Function,Vector{Int}} )
79
+ max_key = maximum (keys (explorer. concepts); init = 0 )
80
+ explorer. concepts[max_key+ 1 ] = concept
81
+ return max_key + 1
82
+ end
83
+
84
+ function delete_concept! (explorer:: Explorer , key:: Int )
85
+ delete! (explorer. concepts, key)
86
+ return nothing
87
+ end
88
+
89
+ function Base. push! (explorer:: Explorer , domain:: AbstractDomain )
90
+ max_key = maximum (keys (explorer. domains); init = 0 )
91
+ explorer. domains[max_key+ 1 ] = domain
92
+ return max_key + 1
93
+ end
94
+
95
+ function delete_domain! (explorer:: Explorer , key:: Int )
96
+ delete! (explorer. domains, key)
97
+ return nothing
98
+ end
99
+
100
+ set! (explorer:: Explorer , objective:: Function ) = explorer. objective = objective
101
+
102
+ function update_exploration! (explorer, f, c, search = explorer. settings. search)
103
+ solutions = explorer. state. solutions
104
+ non_sltns = explorer. state. non_solutions
105
+ obj = explorer. objective
106
+ sl = search == :complete ? Inf : explorer. settings. solutions_limit
107
+
108
+ cv = collect (c)
109
+ if f (cv)
110
+ if length (solutions) < sl
111
+ push! (solutions, cv)
112
+ obj != = nothing && (explorer. state. best = argmin (obj, solutions))
113
+ end
114
+ else
115
+ if length (non_sltns) < sl
116
+ push! (non_sltns, cv)
117
+ end
118
+ end
119
+ return nothing
120
+ end
121
+
37
122
"""
38
123
_explore(args...)
39
124
40
125
Internals of the `explore` function. Behavior is automatically adjusted on the kind of exploration: `:flexible`, `:complete`, `:partial`.
41
126
"""
42
- function _explore (domains , f, s , :: Val{:partial} )
43
- solutions = Set {Vector{Int}} ()
44
- non_sltns = Set {Vector{Int}} ()
127
+ function _explore! (explorer , f, :: Val{:partial} )
128
+ sl = explorer . settings . solutions_limit
129
+ ms = explorer . settings . max_samplings
45
130
46
- sl = s. solutions_limit
131
+ solutions = explorer. state. solutions
132
+ non_sltns = explorer. state. non_solutions
133
+ domains = explorer. domains |> values
47
134
48
- for _ = 1 : s . max_samplings
135
+ for _ = 1 : ms
49
136
length (solutions) ≥ sl && length (non_sltns) ≥ sl && break
50
137
config = map (rand, domains)
51
- c = f (config) ? solutions : non_sltns
52
- length (c) < sl && push! (c, config)
138
+ update_exploration! (explorer, f, config)
53
139
end
54
- return solutions, non_sltns
140
+ return nothing
55
141
end
56
142
57
- function _explore (domains, f, :: ExploreSettings , :: Val{:complete} )
58
- solutions = Set {Vector{Int}} ()
59
- non_sltns = Set {Vector{Int}} ()
60
-
61
- configurations = Base. Iterators. product (map (d -> get_domain (d), domains)... )
62
- foreach (
63
- c -> (cv = collect (c); push! (f (cv) ? solutions : non_sltns, cv)),
64
- configurations,
65
- )
66
- return solutions, non_sltns
143
+ function _explore! (explorer, f, :: Val{:complete} )
144
+ C = Base. Iterators. product (map (d -> get_domain (d), explorer. domains |> values)... )
145
+ foreach (c -> update_exploration! (explorer, f, c, :complete ), C)
146
+ return nothing
67
147
end
68
148
69
- function _explore (domains, f, s, :: Val{:flexible} )
70
- search = s. max_samplings < s. complete_search_limit ? :complete : :partial
71
- return _explore (domains, f, s, Val (search))
149
+ function explore! (explorer:: Explorer )
150
+ c =
151
+ x -> all ([
152
+ f (isempty (vars) ? x : @view x[vars]) for
153
+ (f, vars) in explorer. concepts |> values
154
+ ])
155
+ s = explorer. settings
156
+ search = s. search
157
+ if search == :flexible
158
+ search = s. max_samplings < s. complete_search_limit ? :complete : :partial
159
+ end
160
+ return _explore! (explorer, c, Val (search))
72
161
end
73
162
74
163
"""
@@ -87,7 +176,9 @@ Search (a part of) a search space and return a pair of vectors of configurations
87
176
"""
88
177
function explore (domains, concept; settings = ExploreSettings (domains), parameters... )
89
178
f = x -> concept (x; parameters... )
90
- return _explore (domains, f, settings, Val (settings. search))
179
+ explorer = Explorer ([(f, Vector {Int} ())], domains; settings)
180
+ explore! (explorer)
181
+ return explorer. state. solutions, explorer. state. non_solutions
91
182
end
92
183
93
184
# # SECTION - Test Items
96
187
X, X̅ = explore (domains, allunique)
97
188
@test length (X) == factorial (4 )
98
189
@test length (X̅) == 4 ^ 4 - factorial (4 )
190
+
191
+ explorer = ConstraintDomains. Explorer ()
99
192
end
0 commit comments