Skip to content

Commit 6fc0735

Browse files
aleksander-mendozaAlagrismtf90
authored
Add OSTIA algorithm (#74)
* OSTIA sketch * initial refactoring into separate module * initial integration of LearnLib/AutomataLib interfaces * small adjustment in tests * renaming (Sub)SequentialTransducer * fixed IllegalArgumentException, onwardForm algorithm, minor refactorization * add utility classes and provide alternative onward computation * fixed OSTIA buildPtt procedure to allow for non-sorted informants, minor improvements and optimizations * cleanups and refactorings * removed dead code * refactored some interfaces/classes * added new test cases * applied style guidelines * OSTIA characteristic sample * some more refactorings * documentation * move some utility to AutomataLib * streamlining interfaces * attempt at handling initial states in onward transformation * fix onward computation * some more cleanups * switch to the development version of AutomataLib * fixes bug in blue-fringe * some minor cleanups * refactoring the `State` class * fix issues reported by the code-anylsis tools * brought back formal guarantees * aggregate shared data in parent class * add some more test cases * make null-analysis happy Co-authored-by: Alagris <[email protected]> Co-authored-by: Markus Frohme <[email protected]>
1 parent 9f78eb3 commit 6fc0735

File tree

23 files changed

+1359
-4
lines changed

23 files changed

+1359
-4
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
66

77
[Full changelog](https://github.com/LearnLib/learnlib/compare/learnlib-0.16.0...HEAD)
88

9+
### Added
10+
11+
* Added the OSTIA passive learning algorithm, thanks to [Aleksander Mendoza-Drosik](https://github.com/aleksander-mendoza).
12+
913
### Changed
1014

1115
* `PassiveLearningAlgorithm#comuteModel` did not specify whether repeated calls to the method should yield identical models. It is now explicitly left open to the respective implementation to support this behavior. `BlueFringeRPNI{DFA,Mealy}` explicitly does not support this behavior, as the internal prefix-tree acceptors is now constructed on-the-fly as samples are added via the `addSample` methods. This allows to drop the previously redundant caching of samples and reduce memory pressure. `BlueFringeEDSMDFA` and `BlueFringeMDLDFA` still have to cache the samples internally and therefore still support repeated model construction.

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,10 @@ Currently the following learning algorithms with respective target models are su
2020

2121
Algorithm (active) | Target models || Algorithm (passive) | Models
2222
--- | --- | --- | --- | ---
23-
ADT | `Mealy` || RPNI | `DFA` `Mealy`
24-
DHC | `Mealy` || RPNI (EDSM) | `DFA`
25-
Discrimination Tree | `DFA` `Mealy` `VPDA` || RPNI (MDL) | `DFA`
26-
Kearns & Vazirani | `DFA` `Mealy`
23+
ADT | `Mealy` || OSTIA | `SST`
24+
DHC | `Mealy` || RPNI | `DFA`
25+
Discrimination Tree | `DFA` `Mealy` `VPDA` || RPNI (EDSM) | `DFA`
26+
Kearns & Vazirani | `DFA` `Mealy` || RPNI (MDL) | `DFA`
2727
L* (incl. variants) | `DFA` `Mealy`
2828
NL* | `NFA`
2929
TTT | `DFA` `Mealy` `VPDA`

algorithms/passive/ostia/pom.xml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
Copyright (C) 2013-2020 TU Dortmund
4+
This file is part of LearnLib, http://www.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 http://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-passive-parent</artifactId>
24+
<version>0.17.0-SNAPSHOT</version>
25+
</parent>
26+
27+
<artifactId>learnlib-ostia</artifactId>
28+
29+
<name>LearnLib :: Algorithms :: OSTIA</name>
30+
<description>The OSTIA passive learning algorithm</description>
31+
32+
<dependencies>
33+
<dependency>
34+
<groupId>de.learnlib</groupId>
35+
<artifactId>learnlib-api</artifactId>
36+
</dependency>
37+
38+
<dependency>
39+
<groupId>net.automatalib</groupId>
40+
<artifactId>automata-api</artifactId>
41+
</dependency>
42+
<dependency>
43+
<groupId>net.automatalib</groupId>
44+
<artifactId>automata-commons-smartcollections</artifactId>
45+
</dependency>
46+
<dependency>
47+
<groupId>net.automatalib</groupId>
48+
<artifactId>automata-commons-util</artifactId>
49+
</dependency>
50+
<dependency>
51+
<groupId>net.automatalib</groupId>
52+
<artifactId>automata-core</artifactId>
53+
</dependency>
54+
55+
<dependency>
56+
<groupId>org.checkerframework</groupId>
57+
<artifactId>checker-qual</artifactId>
58+
</dependency>
59+
60+
<!-- test -->
61+
<dependency>
62+
<groupId>com.google.guava</groupId>
63+
<artifactId>guava</artifactId>
64+
<scope>test</scope>
65+
</dependency>
66+
67+
<dependency>
68+
<groupId>de.learnlib.testsupport</groupId>
69+
<artifactId>learnlib-learner-it-support</artifactId>
70+
</dependency>
71+
72+
<dependency>
73+
<groupId>net.automatalib</groupId>
74+
<artifactId>automata-serialization-dot</artifactId>
75+
<scope>test</scope>
76+
</dependency>
77+
<dependency>
78+
<groupId>net.automatalib</groupId>
79+
<artifactId>automata-util</artifactId>
80+
<scope>test</scope>
81+
</dependency>
82+
83+
<dependency>
84+
<groupId>org.testng</groupId>
85+
<artifactId>testng</artifactId>
86+
</dependency>
87+
</dependencies>
88+
</project>
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* Copyright (C) 2013-2020 TU Dortmund
2+
* This file is part of LearnLib, http://www.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.algorithms.ostia;
17+
18+
import org.checkerframework.checker.nullness.qual.Nullable;
19+
20+
/**
21+
* @author Aleksander Mendoza-Drosik
22+
*/
23+
class Blue {
24+
25+
final State parent;
26+
final int symbol;
27+
28+
Blue(State parent, int symbol) {
29+
this.symbol = symbol;
30+
this.parent = parent;
31+
}
32+
33+
@Nullable State state() {
34+
final @Nullable Edge edge = parent.transitions[symbol];
35+
assert edge != null;
36+
return edge.target;
37+
}
38+
39+
@Override
40+
public String toString() {
41+
return String.valueOf(state());
42+
}
43+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/* Copyright (C) 2013-2020 TU Dortmund
2+
* This file is part of LearnLib, http://www.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.algorithms.ostia;
17+
18+
import org.checkerframework.checker.nullness.qual.Nullable;
19+
20+
/**
21+
* @author Aleksander Mendoza-Drosik
22+
*/
23+
class Edge {
24+
25+
@Nullable IntQueue out;
26+
State target;
27+
28+
Edge() {}
29+
30+
Edge(Edge edge) {
31+
out = IntQueue.copyAndConcat(edge.out, null);
32+
target = edge.target;
33+
}
34+
35+
@Override
36+
public String toString() {
37+
return String.valueOf(target);
38+
}
39+
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/* Copyright (C) 2013-2020 TU Dortmund
2+
* This file is part of LearnLib, http://www.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.algorithms.ostia;
17+
18+
import java.util.HashSet;
19+
import java.util.Set;
20+
import java.util.StringJoiner;
21+
22+
import net.automatalib.commons.smartcollections.IntSeq;
23+
import org.checkerframework.checker.nullness.qual.Nullable;
24+
import org.checkerframework.checker.nullness.qual.PolyNull;
25+
26+
/**
27+
* @author Aleksander Mendoza-Drosik
28+
*/
29+
class IntQueue {
30+
31+
int value;
32+
@Nullable IntQueue next;
33+
34+
@Override
35+
public String toString() {
36+
final StringJoiner sj = new StringJoiner(", ", "[", "]");
37+
38+
IntQueue iter = this;
39+
while (iter != null) {
40+
sj.add(Integer.toString(iter.value));
41+
iter = iter.next;
42+
}
43+
return sj.toString();
44+
}
45+
46+
static @Nullable IntQueue asQueue(IntSeq str) {
47+
IntQueue q = null;
48+
for (int i = str.size() - 1; i >= 0; i--) {
49+
IntQueue next = new IntQueue();
50+
next.value = str.get(i);
51+
next.next = q;
52+
q = next;
53+
}
54+
assert !IntQueue.hasCycle(q);
55+
return q;
56+
}
57+
58+
static boolean eq(@Nullable IntQueue a, @Nullable IntQueue b) {
59+
IntQueue aIter = a;
60+
IntQueue bIter = b;
61+
while (aIter != null && bIter != null) {
62+
if (aIter.value != bIter.value) {
63+
return false;
64+
}
65+
aIter = aIter.next;
66+
bIter = bIter.next;
67+
}
68+
return aIter == null && bIter == null;
69+
}
70+
71+
static boolean hasCycle(@Nullable IntQueue q) {
72+
final Set<IntQueue> elements = new HashSet<>();
73+
IntQueue iter = q;
74+
while (iter != null) {
75+
if (!elements.add(iter)) {
76+
return true;
77+
}
78+
iter = iter.next;
79+
}
80+
return false;
81+
}
82+
83+
static @PolyNull IntQueue copyAndConcat(@Nullable IntQueue q, @PolyNull IntQueue tail) {
84+
assert !hasCycle(q) && !hasCycle(tail);
85+
if (q == null) {
86+
return tail;
87+
}
88+
final IntQueue root = new IntQueue();
89+
root.value = q.value;
90+
IntQueue curr = root;
91+
IntQueue iter = q.next;
92+
while (iter != null) {
93+
curr.next = new IntQueue();
94+
curr = curr.next;
95+
curr.value = iter.value;
96+
iter = iter.next;
97+
}
98+
curr.next = tail;
99+
assert !hasCycle(root);
100+
return root;
101+
}
102+
}

0 commit comments

Comments
 (0)