Skip to content

Commit 868d975

Browse files
Sparse Learner (#152)
* added sparse learner * fixed comment * adjustments for code style * extended contributor list * extended test cases * Revert "extended test cases" This reverts commit 32953b5. * cleanups * some nullability augmentations * more cleanups * more cleanups * update README * update changelog * add DOIs * reverted some refactorings and extended comments * improved documentation * use Java 17 language features * ctrl + f * remove redundant whitespaces * properly order contributors * make checkerframework happy * shortened varnames for readability * replaced confusing getOrDefault call * adjust to upstream changes --------- Co-authored-by: Markus Frohme <markus.frohme@udo.edu> Co-authored-by: Markus Frohme <mtf90@users.noreply.github.com>
1 parent c01b890 commit 868d975

16 files changed

Lines changed: 937 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
99
### Added
1010

1111
* Added a new (L*-based) learning algorithm for *Mealy machines with local timers* (MMLTs), including support for parallel queries, caching, and conformance testing (thanks to [Paul Kogel](https://github.com/pdev55)).
12+
* Added the L<sup>s</sup> active learning algorithm for Mealy machines (thanks to [Wolffhardt Schwabe](https://github.com/stateMachinist)).
1213
* Added an `EarlyExitEQOracle` which for a given `AdaptiveMembershipOracle` and `TestWordGenerator` stops the evaluation of (potentially long) Mealy-based equivalence tests as soon as a mismatch with the hypothesis is detected, potentially improving the symbol performance of the given equivalence oracle.
1314

1415
### Changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Currently, the following learning algorithms with respective target models are s
2424
| DHC | `Mealy` | | | |
2525
| Kearns & Vazirani | `DFA` `Mealy` | | | |
2626
| Lambda | `DFA` `Mealy` | | | |
27+
| L<sup>s</sup> | `Mealy` | | | |
2728
| L# | `Mealy` | | | |
2829
| L* (incl. variants) | `DFA` `Mealy` `Moore` `MMLT` | | | |
2930
| NL* | `NFA` | | | |

algorithms/active/pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ limitations under the License.
4343
<module>observation-pack</module>
4444
<module>observation-pack-vpa</module>
4545
<module>procedural</module>
46+
<module>sparse</module>
4647
<module>ttt</module>
4748
<module>ttt-vpa</module>
4849
</modules>

algorithms/active/sparse/pom.xml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?xml version="1.0"?>
2+
<!--
3+
Copyright (C) 2013-2025 TU Dortmund University
4+
This file is part of LearnLib <https://learnlib.de>.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
-->
18+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
19+
<modelVersion>4.0.0</modelVersion>
20+
21+
<parent>
22+
<groupId>de.learnlib</groupId>
23+
<artifactId>learnlib-algorithms-active-parent</artifactId>
24+
<version>0.19.0-SNAPSHOT</version>
25+
<relativePath>../pom.xml</relativePath>
26+
</parent>
27+
28+
<artifactId>learnlib-sparse</artifactId>
29+
30+
<name>LearnLib :: Algorithms :: Sparse</name>
31+
<description>
32+
This artifact provides the implementation of the Sparse OT learning algorithm as described in the paper
33+
"Learning Mealy Machines with Sparse Observation Tables" (https://doi.org/10.1007/978-3-032-05792-1_10) by
34+
Wolffhardt Schwabe, Paul Kogel, and Sabine Glesner.
35+
</description>
36+
37+
<dependencies>
38+
<!-- internal -->
39+
<dependency>
40+
<groupId>de.learnlib</groupId>
41+
<artifactId>learnlib-api</artifactId>
42+
</dependency>
43+
<dependency>
44+
<groupId>de.learnlib</groupId>
45+
<artifactId>learnlib-counterexamples</artifactId>
46+
</dependency>
47+
<dependency>
48+
<groupId>de.learnlib</groupId>
49+
<artifactId>learnlib-util</artifactId>
50+
</dependency>
51+
52+
<!-- external -->
53+
<dependency>
54+
<groupId>net.automatalib</groupId>
55+
<artifactId>automata-api</artifactId>
56+
</dependency>
57+
<dependency>
58+
<groupId>net.automatalib</groupId>
59+
<artifactId>automata-commons-util</artifactId>
60+
</dependency>
61+
<dependency>
62+
<groupId>net.automatalib</groupId>
63+
<artifactId>automata-core</artifactId>
64+
</dependency>
65+
66+
<dependency>
67+
<groupId>org.checkerframework</groupId>
68+
<artifactId>checker-qual</artifactId>
69+
</dependency>
70+
71+
<!-- testing -->
72+
<dependency>
73+
<groupId>de.learnlib.testsupport</groupId>
74+
<artifactId>learnlib-learner-it-support</artifactId>
75+
</dependency>
76+
</dependencies>
77+
</project>
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* Copyright (C) 2013-2025 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.algorithm.sparse;
17+
18+
import java.util.HashMap;
19+
import java.util.HashSet;
20+
import java.util.Map;
21+
import java.util.Set;
22+
23+
import net.automatalib.word.Word;
24+
25+
/**
26+
* Each core row represents some hypothesis state and stores its outputs for all table suffixes.
27+
*/
28+
class CoreRow<S, I, O> extends Row<S, I, O> {
29+
30+
/**
31+
* Hypothesis state associated with this row.
32+
*/
33+
final S state;
34+
35+
/**
36+
* Index of this row in the core row list. Used as a unique address.
37+
*/
38+
final int idx;
39+
40+
/**
41+
* Maps suffixes to their outputs.
42+
*/
43+
final Map<Word<I>, Word<O>> sufToOut;
44+
45+
/**
46+
* Identifiers of all suffix-output pairs in this row, used for fast compatibility checking.
47+
*/
48+
final Set<Integer> cellIds;
49+
50+
CoreRow(Word<I> prefix, S state, int idx) {
51+
super(prefix);
52+
this.state = state;
53+
this.idx = idx;
54+
sufToOut = new HashMap<>();
55+
cellIds = new HashSet<>(); // use HashSet for fast containment checks
56+
}
57+
58+
void addSuffix(Word<I> suf, Word<O> out, int cell) {
59+
sufToOut.put(suf, out);
60+
cellIds.add(cell);
61+
}
62+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/* Copyright (C) 2013-2025 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.algorithm.sparse;
17+
18+
import net.automatalib.word.Word;
19+
import org.checkerframework.checker.nullness.qual.Nullable;
20+
21+
/**
22+
* Each fringe row represents some hypothesis transition outside the spanning tree defined by the core prefixes.
23+
*
24+
* @param <S>
25+
* state type
26+
* @param <I>
27+
* input symbol type
28+
* @param <O>
29+
* output symbol type
30+
*/
31+
class FringeRow<S, I, O> extends Row<S, I, O> {
32+
33+
/**
34+
* Source state.
35+
*/
36+
final S srcState;
37+
38+
/**
39+
* Input symbol.
40+
*/
41+
final I transIn;
42+
43+
/**
44+
* Output symbol (determined lazily).
45+
*/
46+
O transOut;
47+
48+
/**
49+
* For compression, fringe rows do not store observations directly. Instead, they point to some leaf in a tree
50+
* encoding their classification history. This trick avoids redundantly storing identical observations.
51+
*/
52+
@Nullable Leaf<S, I, O> leaf;
53+
54+
FringeRow(Word<I> prefix, S srcState, Leaf<S, I, O> leaf) {
55+
super(prefix);
56+
this.srcState = srcState;
57+
this.transIn = prefix.lastSymbol();
58+
this.leaf = leaf;
59+
}
60+
}

0 commit comments

Comments
 (0)