• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LearnLib / learnlib / 31619759710

12 Aug 2026 04:27PM UTC coverage: 95.488% (+1.1%) from 94.368%
31619759710

push

github

mtf90
use new version scheme

15533 of 16267 relevant lines covered (95.49%)

1.72 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

98.08
/oracles/parallelism/src/main/java/de/learnlib/oracle/parallelism/ParallelOracleBuilders.java
1
/* Copyright (C) 2013-2026 TU Dortmund University
2
 * This file is part of LearnLib <https://learnlib.de>.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package de.learnlib.oracle.parallelism;
17

18
import java.util.Collection;
19
import java.util.function.Supplier;
20

21
import de.learnlib.oracle.AdaptiveMembershipOracle;
22
import de.learnlib.oracle.MembershipOracle;
23
import de.learnlib.oracle.OmegaMembershipOracle;
24
import de.learnlib.oracle.ThreadPool.PoolPolicy;
25
import de.learnlib.oracle.TimedQueryOracle;
26
import de.learnlib.oracle.membership.AbstractSULOmegaOracle;
27
import de.learnlib.oracle.membership.SULAdaptiveOracle;
28
import de.learnlib.oracle.membership.SULOracle;
29
import de.learnlib.oracle.membership.StateLocalInputSULOracle;
30
import de.learnlib.oracle.membership.TimedSULOracle;
31
import de.learnlib.sul.ObservableSUL;
32
import de.learnlib.sul.SUL;
33
import de.learnlib.sul.StateLocalInputSUL;
34
import de.learnlib.sul.TimedSUL;
35
import de.learnlib.time.MMLTModelParams;
36
import net.automatalib.common.util.collection.CollectionUtil;
37
import net.automatalib.word.Word;
38

39
/**
40
 * Builders for (static and dynamic) parallel oracles.
41
 * <p>
42
 * Using the methods defined in this class is the preferred way of instantiating parallel oracles.
43
 * <p>
44
 * <b>Usage examples</b>
45
 * <p>
46
 * Creating a static parallel oracle with a minimum batch size of 20 and a fixed thread pool, using two membership
47
 * oracles (running in two separate threads):
48
 * <pre>
49
 * ParallelOracleBuilders.newStaticParallelOracle(oracle1, oracle2)
50
 *      .withMinBatchSize(20)
51
 *      .create();
52
 * </pre>
53
 * <p>
54
 * Creating a dynamic parallel oracle with a custom executor, and a batch size of 5, using a shared membership oracle:
55
 * <pre>
56
 * ParallelOracleBuilders.newDynamicParallelOracle(() -&gt; membershipOracle)
57
 *      .withBatchSize(5)
58
 *      .withCustomExecutor(myExecutor)
59
 *      .create();
60
 * </pre>
61
 * <b>Note:</b> This requires the shared membership oracle to be thread-safe.
62
 * <p>
63
 * Creating a dynamic parallel oracle with a cached thread pool of maximum size 4, a batch size of 5, using a (forkable)
64
 * SUL:
65
 * <pre>
66
 * ParallelOracleBuilders.newDynamicParallelOracle(sul)
67
 *      .withBatchSize(5)
68
 *      .withPoolSize(4)
69
 *      .withPoolPolicy(PoolPolicy.CACHED)
70
 *      .create();
71
 * </pre>
72
 */
73
public final class ParallelOracleBuilders {
74

75
    private ParallelOracleBuilders() {
76
        // prevent instantiation
77
    }
78

79
    /**
80
     * Creates a {@link DynamicParallelOracleBuilder} using the provided {@code sul} as a supplier. This requires that
81
     * the sul is {@link SUL#canFork() forkable}.
82
     *
83
     * @param sul
84
     *         the sul instance for spawning new thread-specific membership oracle instances
85
     * @param <I>
86
     *         input symbol type
87
     * @param <O>
88
     *         output domain type
89
     *
90
     * @return a preconfigured oracle builder
91
     */
92
    public static <I, O> DynamicParallelOracleBuilder<I, Word<O>> newDynamicParallelOracle(SUL<I, O> sul) {
93
        checkFork(sul);
2✔
94
        return newDynamicParallelOracle(toSupplier(sul));
2✔
95
    }
96

97
    /**
98
     * Creates a {@link DynamicParallelOracleBuilder} using the provided {@code sul} as a supplier. This requires that
99
     * the sul is {@link SUL#canFork() forkable}.
100
     *
101
     * @param sul
102
     *         the sul instance for spawning new thread-specific membership oracle instances
103
     * @param undefinedInput
104
     *         the input symbol used for responding to inputs that are not
105
     *         {@link StateLocalInputSUL#currentlyEnabledInputs() enabled}.
106
     * @param <I>
107
     *         input symbol type
108
     * @param <O>
109
     *         output domain type
110
     *
111
     * @return a preconfigured oracle builder
112
     */
113
    public static <I, O> DynamicParallelOracleBuilder<I, Word<O>> newDynamicParallelOracle(StateLocalInputSUL<I, O> sul,
114
                                                                                           O undefinedInput) {
115
        checkFork(sul);
2✔
116
        return new DynamicParallelOracleBuilder<>(toSupplier(sul, undefinedInput));
2✔
117
    }
118

119
    /**
120
     * Creates a {@link DynamicParallelOracleBuilder} using the provided supplier.
121
     *
122
     * @param oracleSupplier
123
     *         the supplier for spawning new thread-specific membership oracle instances
124
     * @param <I>
125
     *         input symbol type
126
     * @param <D>
127
     *         output domain type
128
     *
129
     * @return a preconfigured oracle builder
130
     */
131
    public static <I, D> DynamicParallelOracleBuilder<I, D> newDynamicParallelOracle(Supplier<? extends MembershipOracle<I, D>> oracleSupplier) {
132
        return new DynamicParallelOracleBuilder<>(oracleSupplier);
2✔
133
    }
134

135
    /**
136
     * Convenience method for {@link #newDynamicParallelOracle(Collection)}.
137
     *
138
     * @param firstOracle
139
     *         the first (mandatory) oracle
140
     * @param otherOracles
141
     *         further (optional) oracles to be used by other threads
142
     * @param <I>
143
     *         input symbol type
144
     * @param <D>
145
     *         output domain type
146
     *
147
     * @return a preconfigured oracle builder
148
     */
149
    @SafeVarargs
150
    public static <I, D> DynamicParallelOracleBuilder<I, D> newDynamicParallelOracle(MembershipOracle<I, D> firstOracle,
151
                                                                                     MembershipOracle<I, D>... otherOracles) {
152
        return newDynamicParallelOracle(CollectionUtil.list(firstOracle, otherOracles));
2✔
153
    }
154

155
    /**
156
     * Creates a {@link DynamicParallelOracleBuilder} using the provided collection of membership oracles. The resulting
157
     * parallel oracle will always use a {@link PoolPolicy#FIXED} pool policy and spawn a separate thread for each of
158
     * the provided oracles (so that the oracles do not need to care about synchronization if they don't share state).
159
     *
160
     * @param oracles
161
     *         the oracle instances to distribute the queries to
162
     * @param <I>
163
     *         input symbol type
164
     * @param <D>
165
     *         output domain type
166
     *
167
     * @return the preconfigured oracle builder
168
     */
169
    public static <I, D> DynamicParallelOracleBuilder<I, D> newDynamicParallelOracle(Collection<? extends MembershipOracle<I, D>> oracles) {
170
        return new DynamicParallelOracleBuilder<>(oracles);
2✔
171
    }
172

173
    /**
174
     * Creates a {@link DynamicParallelOmegaOracleBuilder} using the provided {@code sul} as a supplier. This requires
175
     * that the sul is {@link SUL#canFork() forkable}.
176
     *
177
     * @param sul
178
     *         the sul instance for spawning new thread-specific omega membership oracle instances
179
     * @param <I>
180
     *         input symbol type
181
     * @param <O>
182
     *         output domain type
183
     *
184
     * @return a preconfigured oracle builder
185
     */
186
    public static <I, O> DynamicParallelOmegaOracleBuilder<?, I, Word<O>> newDynamicParallelOmegaOracle(ObservableSUL<?, I, O> sul) {
187
        checkFork(sul);
2✔
188
        return newDynamicParallelOmegaOracle(toSupplier(sul)::get);
2✔
189
    }
190

191
    /**
192
     * Creates a {@link DynamicParallelOmegaOracleBuilder} using the provided supplier.
193
     *
194
     * @param oracleSupplier
195
     *         the supplier for spawning new thread-specific membership oracle instances
196
     * @param <S>
197
     *         oracle state type
198
     * @param <I>
199
     *         input symbol type
200
     * @param <D>
201
     *         output domain type
202
     *
203
     * @return a preconfigured oracle builder
204
     */
205
    public static <S, I, D> DynamicParallelOmegaOracleBuilder<S, I, D> newDynamicParallelOmegaOracle(Supplier<? extends OmegaMembershipOracle<S, I, D>> oracleSupplier) {
206
        return new DynamicParallelOmegaOracleBuilder<>(oracleSupplier);
2✔
207
    }
208

209
    /**
210
     * Convenience method for {@link #newDynamicParallelOmegaOracle(Collection)}.
211
     *
212
     * @param firstOracle
213
     *         the first (mandatory) oracle
214
     * @param otherOracles
215
     *         further (optional) oracles to be used by other threads
216
     * @param <S>
217
     *         oracle state type
218
     * @param <I>
219
     *         input symbol type
220
     * @param <D>
221
     *         output domain type
222
     *
223
     * @return a preconfigured oracle builder
224
     */
225
    @SafeVarargs
226
    public static <S, I, D> DynamicParallelOmegaOracleBuilder<S, I, D> newDynamicParallelOmegaOracle(
227
            OmegaMembershipOracle<S, I, D> firstOracle,
228
            OmegaMembershipOracle<S, I, D>... otherOracles) {
229
        return newDynamicParallelOmegaOracle(CollectionUtil.list(firstOracle, otherOracles));
2✔
230
    }
231

232
    /**
233
     * Creates a {@link DynamicParallelOmegaOracleBuilder} using the provided collection of membership oracles. The
234
     * resulting parallel oracle will always use a {@link PoolPolicy#FIXED} pool policy and spawn a separate thread for
235
     * each of the provided oracles (so that the oracles do not need to care about synchronization if they don't share
236
     * state).
237
     *
238
     * @param oracles
239
     *         the oracle instances to distribute the queries to
240
     * @param <S>
241
     *         oracle state type
242
     * @param <I>
243
     *         input symbol type
244
     * @param <D>
245
     *         output domain type
246
     *
247
     * @return the preconfigured oracle builder
248
     */
249
    public static <S, I, D> DynamicParallelOmegaOracleBuilder<S, I, D> newDynamicParallelOmegaOracle(Collection<? extends OmegaMembershipOracle<S, I, D>> oracles) {
250
        return new DynamicParallelOmegaOracleBuilder<>(oracles);
2✔
251
    }
252

253
    /**
254
     * Creates a {@link DynamicParallelAdaptiveOracleBuilder} using the provided {@code sul} as a supplier. This
255
     * requires that the sul is {@link SUL#canFork() forkable}.
256
     *
257
     * @param sul
258
     *         the sul instance for spawning new thread-specific omega membership oracle instances
259
     * @param <I>
260
     *         input symbol type
261
     * @param <O>
262
     *         output symbol type
263
     *
264
     * @return a preconfigured oracle builder
265
     */
266
    public static <I, O> DynamicParallelAdaptiveOracleBuilder<I, O> newDynamicParallelAdaptiveOracle(SUL<I, O> sul) {
267
        checkFork(sul);
2✔
268
        return newDynamicParallelAdaptiveOracle(toAdaptiveSupplier(sul));
2✔
269
    }
270

271
    /**
272
     * Creates a {@link DynamicParallelAdaptiveOracleBuilder} using the provided supplier.
273
     *
274
     * @param oracleSupplier
275
     *         the supplier for spawning new thread-specific membership oracle instances
276
     * @param <I>
277
     *         input symbol type
278
     * @param <O>
279
     *         output symbol type
280
     *
281
     * @return a preconfigured oracle builder
282
     */
283
    public static <I, O> DynamicParallelAdaptiveOracleBuilder<I, O> newDynamicParallelAdaptiveOracle(Supplier<? extends AdaptiveMembershipOracle<I, O>> oracleSupplier) {
284
        return new DynamicParallelAdaptiveOracleBuilder<>(oracleSupplier);
2✔
285
    }
286

287
    /**
288
     * Convenience method for {@link #newDynamicParallelAdaptiveOracle(Collection)}.
289
     *
290
     * @param firstOracle
291
     *         the first (mandatory) oracle
292
     * @param otherOracles
293
     *         further (optional) oracles to be used by other threads
294
     * @param <I>
295
     *         input symbol type
296
     * @param <O>
297
     *         output symbol type
298
     *
299
     * @return a preconfigured oracle builder
300
     */
301
    @SafeVarargs
302
    public static <I, O> DynamicParallelAdaptiveOracleBuilder<I, O> newDynamicParallelAdaptiveOracle(
303
            AdaptiveMembershipOracle<I, O> firstOracle,
304
            AdaptiveMembershipOracle<I, O>... otherOracles) {
305
        return newDynamicParallelAdaptiveOracle(CollectionUtil.list(firstOracle, otherOracles));
2✔
306
    }
307

308
    /**
309
     * Creates a {@link DynamicParallelAdaptiveOracleBuilder} using the provided collection of membership oracles. The
310
     * resulting parallel oracle will always use a {@link PoolPolicy#FIXED} pool policy and spawn a separate thread for
311
     * each of the provided oracles (so that the oracles do not need to care about synchronization if they don't share
312
     * state).
313
     *
314
     * @param oracles
315
     *         the oracle instances to distribute the queries to
316
     * @param <I>
317
     *         input symbol type
318
     * @param <O>
319
     *         output symbol type
320
     *
321
     * @return the preconfigured oracle builder
322
     */
323
    public static <I, O> DynamicParallelAdaptiveOracleBuilder<I, O> newDynamicParallelAdaptiveOracle(Collection<? extends AdaptiveMembershipOracle<I, O>> oracles) {
324
        return new DynamicParallelAdaptiveOracleBuilder<>(oracles);
2✔
325
    }
326

327
    /**
328
     * Creates a {@link DynamicParallelTimedQueryOracleBuilder} using the provided {@code sul} as a supplier. This
329
     * requires that the sul is {@link SUL#canFork() forkable}.
330
     *
331
     * @param sul
332
     *         the sul instance for spawning new thread-specific oracle instances
333
     * @param params
334
     *         additional parameters for answering queries
335
     * @param <I>
336
     *         input symbol type (of non-delaying inputs)
337
     * @param <O>
338
     *         output symbol type
339
     *
340
     * @return a preconfigured oracle builder
341
     */
342
    public static <I, O> DynamicParallelTimedQueryOracleBuilder<I, O> newDynamicParallelTimedQueryOracle(TimedSUL<I, O> sul,
343
                                                                                                         MMLTModelParams<O> params) {
344
        checkFork(sul);
2✔
345
        return newDynamicParallelTimedQueryOracle(toSupplier(sul, params));
2✔
346
    }
347

348
    /**
349
     * Creates a {@link DynamicParallelTimedQueryOracleBuilder} using the provided supplier.
350
     *
351
     * @param oracleSupplier
352
     *         the supplier for spawning new thread-specific oracle instances
353
     * @param <I>
354
     *         input symbol type (of non-delaying inputs)
355
     * @param <O>
356
     *         output symbol type
357
     *
358
     * @return a preconfigured oracle builder
359
     */
360
    public static <I, O> DynamicParallelTimedQueryOracleBuilder<I, O> newDynamicParallelTimedQueryOracle(Supplier<? extends TimedQueryOracle<I, O>> oracleSupplier) {
361
        return new DynamicParallelTimedQueryOracleBuilder<>(oracleSupplier);
2✔
362
    }
363

364
    /**
365
     * Convenience method for {@link #newDynamicParallelTimedQueryOracle(Collection)}.
366
     *
367
     * @param firstOracle
368
     *         the first (mandatory) oracle
369
     * @param otherOracles
370
     *         further (optional) oracles to be used by other threads
371
     * @param <I>
372
     *         input symbol type (of non-delaying inputs)
373
     * @param <O>
374
     *         output symbol type
375
     *
376
     * @return a preconfigured oracle builder
377
     */
378
    @SafeVarargs
379
    public static <I, O> DynamicParallelTimedQueryOracleBuilder<I, O> newDynamicParallelTimedQueryOracle(
380
            TimedQueryOracle<I, O> firstOracle,
381
            TimedQueryOracle<I, O>... otherOracles) {
382
        return newDynamicParallelTimedQueryOracle(CollectionUtil.list(firstOracle, otherOracles));
2✔
383
    }
384

385
    /**
386
     * Creates a {@link DynamicParallelTimedQueryOracleBuilder} using the provided collection of membership oracles. The
387
     * resulting parallel oracle will always use a {@link PoolPolicy#FIXED} pool policy and spawn a separate thread for
388
     * each of the provided oracles (so that the oracles do not need to care about synchronization if they don't share
389
     * state).
390
     *
391
     * @param oracles
392
     *         the oracle instances to distribute the queries to
393
     * @param <I>
394
     *         input symbol type (of non-delaying inputs)
395
     * @param <O>
396
     *         output symbol type
397
     *
398
     * @return the preconfigured oracle builder
399
     */
400
    public static <I, O> DynamicParallelTimedQueryOracleBuilder<I, O> newDynamicParallelTimedQueryOracle(Collection<? extends TimedQueryOracle<I, O>> oracles) {
401
        return new DynamicParallelTimedQueryOracleBuilder<>(oracles);
2✔
402
    }
403

404
    /**
405
     * Creates a {@link StaticParallelOracleBuilder} using the provided {@code sul} as a supplier. This requires that
406
     * the sul is {@link SUL#canFork() forkable}.
407
     *
408
     * @param sul
409
     *         the sul instance for spawning new thread-specific membership oracle instances
410
     * @param <I>
411
     *         input symbol type
412
     * @param <O>
413
     *         output domain type
414
     *
415
     * @return a preconfigured oracle builder
416
     */
417
    public static <I, O> StaticParallelOracleBuilder<I, Word<O>> newStaticParallelOracle(SUL<I, O> sul) {
418
        checkFork(sul);
2✔
419
        return newStaticParallelOracle(toSupplier(sul));
2✔
420
    }
421

422
    /**
423
     * Creates a {@link StaticParallelOracleBuilder} using the provided {@code sul} as a supplier. This requires that
424
     * the sul is {@link SUL#canFork() forkable}.
425
     *
426
     * @param sul
427
     *         the sul instance for spawning new thread-specific membership oracle instances
428
     * @param undefinedInput
429
     *         the input symbol used for responding to inputs that are not
430
     *         {@link StateLocalInputSUL#currentlyEnabledInputs() enabled}.
431
     * @param <I>
432
     *         input symbol type
433
     * @param <O>
434
     *         output domain type
435
     *
436
     * @return a preconfigured oracle builder
437
     */
438
    public static <I, O> StaticParallelOracleBuilder<I, Word<O>> newStaticParallelOracle(StateLocalInputSUL<I, O> sul,
439
                                                                                         O undefinedInput) {
440
        checkFork(sul);
2✔
441
        return new StaticParallelOracleBuilder<>(toSupplier(sul, undefinedInput));
2✔
442
    }
443

444
    /**
445
     * Creates a {@link StaticParallelOracleBuilder} using the provided supplier. Uses the further specified
446
     * {@link StaticParallelOracleBuilder#withPoolPolicy(PoolPolicy)} and
447
     * {@link StaticParallelOracleBuilder#withNumInstances(int)}} (or its defaults) to determine the thread pool.
448
     *
449
     * @param oracleSupplier
450
     *         the supplier for spawning new thread-specific membership oracle instances
451
     * @param <I>
452
     *         input symbol type
453
     * @param <D>
454
     *         output domain type
455
     *
456
     * @return a preconfigured oracle builder
457
     */
458
    public static <I, D> StaticParallelOracleBuilder<I, D> newStaticParallelOracle(Supplier<? extends MembershipOracle<I, D>> oracleSupplier) {
459
        return new StaticParallelOracleBuilder<>(oracleSupplier);
2✔
460
    }
461

462
    /**
463
     * Convenience method for {@link #newStaticParallelOracle(Collection)}.
464
     *
465
     * @param firstOracle
466
     *         the first (mandatory) oracle
467
     * @param otherOracles
468
     *         further (optional) oracles to be used by other threads
469
     * @param <I>
470
     *         input symbol type
471
     * @param <D>
472
     *         output domain type
473
     *
474
     * @return a preconfigured oracle builder
475
     */
476
    @SafeVarargs
477
    public static <I, D> StaticParallelOracleBuilder<I, D> newStaticParallelOracle(MembershipOracle<I, D> firstOracle,
478
                                                                                   MembershipOracle<I, D>... otherOracles) {
479
        return newStaticParallelOracle(CollectionUtil.list(firstOracle, otherOracles));
2✔
480
    }
481

482
    /**
483
     * Creates a {@link StaticParallelOracleBuilder} using the provided collection of membership oracles. The resulting
484
     * parallel oracle will always use a {@link PoolPolicy#FIXED} pool policy and spawn a separate thread for each of
485
     * the provided oracles (so that the oracles do not need to care about synchronization if they don't share state).
486
     *
487
     * @param oracles
488
     *         the oracle instances to distribute the queries to
489
     * @param <I>
490
     *         input symbol type
491
     * @param <D>
492
     *         output domain type
493
     *
494
     * @return the preconfigured oracle builder
495
     */
496
    public static <I, D> StaticParallelOracleBuilder<I, D> newStaticParallelOracle(Collection<? extends MembershipOracle<I, D>> oracles) {
497
        return new StaticParallelOracleBuilder<>(oracles);
2✔
498
    }
499

500
    /**
501
     * Creates a {@link StaticParallelOmegaOracleBuilder} using the provided {@code sul} as a supplier. This requires
502
     * that the sul is {@link SUL#canFork() forkable}.
503
     *
504
     * @param sul
505
     *         the sul instance for spawning new thread-specific omega membership oracle instances
506
     * @param <I>
507
     *         input symbol type
508
     * @param <O>
509
     *         output domain type
510
     *
511
     * @return a preconfigured oracle builder
512
     */
513
    public static <I, O> StaticParallelOmegaOracleBuilder<?, I, Word<O>> newStaticParallelOmegaOracle(ObservableSUL<?, I, O> sul) {
514
        checkFork(sul);
2✔
515
        return newStaticParallelOmegaOracle(toSupplier(sul)::get);
2✔
516
    }
517

518
    /**
519
     * Creates a {@link StaticParallelOmegaOracleBuilder} using the provided supplier.
520
     *
521
     * @param oracleSupplier
522
     *         the supplier for spawning new thread-specific membership oracle instances
523
     * @param <S>
524
     *         oracle state type
525
     * @param <I>
526
     *         input symbol type
527
     * @param <D>
528
     *         output domain type
529
     *
530
     * @return a preconfigured oracle builder
531
     */
532
    public static <S, I, D> StaticParallelOmegaOracleBuilder<S, I, D> newStaticParallelOmegaOracle(Supplier<? extends OmegaMembershipOracle<S, I, D>> oracleSupplier) {
533
        return new StaticParallelOmegaOracleBuilder<>(oracleSupplier);
2✔
534
    }
535

536
    /**
537
     * Convenience method for {@link #newStaticParallelOmegaOracle(Collection)}.
538
     *
539
     * @param firstOracle
540
     *         the first (mandatory) oracle
541
     * @param otherOracles
542
     *         further (optional) oracles to be used by other threads
543
     * @param <S>
544
     *         oracle state type
545
     * @param <I>
546
     *         input symbol type
547
     * @param <D>
548
     *         output domain type
549
     *
550
     * @return a preconfigured oracle builder
551
     */
552
    @SafeVarargs
553
    public static <S, I, D> StaticParallelOmegaOracleBuilder<S, I, D> newStaticParallelOmegaOracle(OmegaMembershipOracle<S, I, D> firstOracle,
554
                                                                                                   OmegaMembershipOracle<S, I, D>... otherOracles) {
555
        return newStaticParallelOmegaOracle(CollectionUtil.list(firstOracle, otherOracles));
2✔
556
    }
557

558
    /**
559
     * Creates a {@link StaticParallelOmegaOracleBuilder} using the provided collection of membership oracles. The
560
     * resulting parallel oracle will always use a {@link PoolPolicy#FIXED} pool policy and spawn a separate thread for
561
     * each of the provided oracles (so that the oracles do not need to care about synchronization if they don't share
562
     * state).
563
     *
564
     * @param oracles
565
     *         the oracle instances to distribute the queries to
566
     * @param <S>
567
     *         oracle state type
568
     * @param <I>
569
     *         input symbol type
570
     * @param <D>
571
     *         output domain type
572
     *
573
     * @return the preconfigured oracle builder
574
     */
575
    public static <S, I, D> StaticParallelOmegaOracleBuilder<S, I, D> newStaticParallelOmegaOracle(Collection<? extends OmegaMembershipOracle<S, I, D>> oracles) {
576
        return new StaticParallelOmegaOracleBuilder<>(oracles);
2✔
577
    }
578

579
    /**
580
     * Creates a {@link StaticParallelAdaptiveOracleBuilder} using the provided {@code sul} as a supplier. This requires
581
     * that the sul is {@link SUL#canFork() forkable}.
582
     *
583
     * @param sul
584
     *         the sul instance for spawning new thread-specific omega membership oracle instances
585
     * @param <I>
586
     *         input symbol type
587
     * @param <O>
588
     *         output domain type
589
     *
590
     * @return a preconfigured oracle builder
591
     */
592
    public static <I, O> StaticParallelAdaptiveOracleBuilder<I, O> newStaticParallelAdaptiveOracle(SUL<I, O> sul) {
593
        checkFork(sul);
2✔
594
        return newStaticParallelAdaptiveOracle(toAdaptiveSupplier(sul));
2✔
595
    }
596

597
    /**
598
     * Creates a {@link StaticParallelAdaptiveOracleBuilder} using the provided supplier.
599
     *
600
     * @param oracleSupplier
601
     *         the supplier for spawning new thread-specific membership oracle instances
602
     * @param <I>
603
     *         input symbol type
604
     * @param <O>
605
     *         output symbol type
606
     *
607
     * @return a preconfigured oracle builder
608
     */
609
    public static <I, O> StaticParallelAdaptiveOracleBuilder<I, O> newStaticParallelAdaptiveOracle(Supplier<? extends AdaptiveMembershipOracle<I, O>> oracleSupplier) {
610
        return new StaticParallelAdaptiveOracleBuilder<>(oracleSupplier);
2✔
611
    }
612

613
    /**
614
     * Convenience method for {@link #newStaticParallelAdaptiveOracle(Collection)}.
615
     *
616
     * @param firstOracle
617
     *         the first (mandatory) oracle
618
     * @param otherOracles
619
     *         further (optional) oracles to be used by other threads
620
     * @param <I>
621
     *         input symbol type
622
     * @param <O>
623
     *         output symbol type
624
     *
625
     * @return a preconfigured oracle builder
626
     */
627
    @SafeVarargs
628
    public static <I, O> StaticParallelAdaptiveOracleBuilder<I, O> newStaticParallelAdaptiveOracle(
629
            AdaptiveMembershipOracle<I, O> firstOracle,
630
            AdaptiveMembershipOracle<I, O>... otherOracles) {
631
        return newStaticParallelAdaptiveOracle(CollectionUtil.list(firstOracle, otherOracles));
2✔
632
    }
633

634
    /**
635
     * Creates a {@link StaticParallelAdaptiveOracleBuilder} using the provided collection of membership oracles. The
636
     * resulting parallel oracle will always use a {@link PoolPolicy#FIXED} pool policy and spawn a separate thread for
637
     * each of the provided oracles (so that the oracles do not need to care about synchronization if they don't share
638
     * state).
639
     *
640
     * @param oracles
641
     *         the oracle instances to distribute the queries to
642
     * @param <I>
643
     *         input symbol type
644
     * @param <O>
645
     *         output symbol type
646
     *
647
     * @return the preconfigured oracle builder
648
     */
649
    public static <I, O> StaticParallelAdaptiveOracleBuilder<I, O> newStaticParallelAdaptiveOracle(Collection<? extends AdaptiveMembershipOracle<I, O>> oracles) {
650
        return new StaticParallelAdaptiveOracleBuilder<>(oracles);
2✔
651
    }
652

653
    /**
654
     * Creates a {@link StaticParallelTimedQueryOracleBuilder} using the provided {@code sul} as a supplier. This
655
     * requires that the sul is {@link SUL#canFork() forkable}.
656
     *
657
     * @param sul
658
     *         the sul instance for spawning new thread-specific oracle instances
659
     * @param params
660
     *         additional parameters for answering queries
661
     * @param <I>
662
     *         input symbol type (of non-delaying inputs)
663
     * @param <O>
664
     *         output symbol type
665
     *
666
     * @return a preconfigured oracle builder
667
     */
668
    public static <I, O> StaticParallelTimedQueryOracleBuilder<I, O> newStaticParallelTimedQueryOracle(TimedSUL<I, O> sul,
669
                                                                                                       MMLTModelParams<O> params) {
670
        checkFork(sul);
2✔
671
        return newStaticParallelTimedQueryOracle(toSupplier(sul, params));
2✔
672
    }
673

674
    /**
675
     * Creates a {@link StaticParallelTimedQueryOracleBuilder} using the provided supplier.
676
     *
677
     * @param oracleSupplier
678
     *         the supplier for spawning new thread-specific oracle instances
679
     * @param <I>
680
     *         input symbol type (of non-delaying inputs)
681
     * @param <O>
682
     *         output symbol type
683
     *
684
     * @return a preconfigured oracle builder
685
     */
686
    public static <I, O> StaticParallelTimedQueryOracleBuilder<I, O> newStaticParallelTimedQueryOracle(Supplier<? extends TimedQueryOracle<I, O>> oracleSupplier) {
687
        return new StaticParallelTimedQueryOracleBuilder<>(oracleSupplier);
2✔
688
    }
689

690
    /**
691
     * Convenience method for {@link #newStaticParallelTimedQueryOracle(Collection)}.
692
     *
693
     * @param firstOracle
694
     *         the first (mandatory) oracle
695
     * @param otherOracles
696
     *         further (optional) oracles to be used by other threads
697
     * @param <I>
698
     *         input symbol type (of non-delaying inputs)
699
     * @param <O>
700
     *         output symbol type
701
     *
702
     * @return a preconfigured oracle builder
703
     */
704
    @SafeVarargs
705
    public static <I, O> StaticParallelTimedQueryOracleBuilder<I, O> newStaticParallelTimedQueryOracle(TimedQueryOracle<I, O> firstOracle,
706
                                                                                                       TimedQueryOracle<I, O>... otherOracles) {
707
        return newStaticParallelTimedQueryOracle(CollectionUtil.list(firstOracle, otherOracles));
2✔
708
    }
709

710
    /**
711
     * Creates a {@link StaticParallelTimedQueryOracleBuilder} using the provided collection of membership oracles. The
712
     * resulting parallel oracle will always use a {@link PoolPolicy#FIXED} pool policy and spawn a separate thread for
713
     * each of the provided oracles (so that the oracles do not need to care about synchronization if they don't share
714
     * state).
715
     *
716
     * @param oracles
717
     *         the oracle instances to distribute the queries to
718
     * @param <I>
719
     *         input symbol type (of non-delaying inputs)
720
     * @param <O>
721
     *         output symbol type
722
     *
723
     * @return the preconfigured oracle builder
724
     */
725
    public static <I, O> StaticParallelTimedQueryOracleBuilder<I, O> newStaticParallelTimedQueryOracle(Collection<? extends TimedQueryOracle<I, O>> oracles) {
726
        return new StaticParallelTimedQueryOracleBuilder<>(oracles);
2✔
727
    }
728

729
    private static <I, O> Supplier<SULOracle<I, O>> toSupplier(SUL<I, O> sul) {
730
        return () -> new SULOracle<>(sul.fork());
2✔
731
    }
732

733
    private static <I, O> Supplier<StateLocalInputSULOracle<I, O>> toSupplier(StateLocalInputSUL<I, O> sul,
734
                                                                              O undefinedSymbol) {
735
        return () -> new StateLocalInputSULOracle<>(sul.fork(), undefinedSymbol);
2✔
736
    }
737

738
    private static <S, I, O> Supplier<OmegaMembershipOracle<?, I, Word<O>>> toSupplier(ObservableSUL<S, I, O> sul) {
739
        return () -> AbstractSULOmegaOracle.newOracle(sul.fork());
2✔
740
    }
741

742
    private static <I, O> Supplier<TimedSULOracle<I, O>> toSupplier(TimedSUL<I, O> sul, MMLTModelParams<O> params) {
743
        return () -> new TimedSULOracle<>(sul.fork(), params);
2✔
744
    }
745

746
    private static <I, O> Supplier<AdaptiveMembershipOracle<I, O>> toAdaptiveSupplier(SUL<I, O> sul) {
747
        return () -> new SULAdaptiveOracle<>(sul.fork());
2✔
748
    }
749

750
    private static <I, O> void checkFork(SUL<I, O> sul) {
751
        if (!sul.canFork()) {
2✔
752
            throw new IllegalArgumentException("SUL must be forkable for parallel processing");
×
753
        }
754
    }
2✔
755
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc