Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSTIA #74

Merged
merged 22 commits into from
Jan 2, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).

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

### Added

* Added the OSTIA passive learning algorithm, thanks to [Aleksander Mendoza-Drosik](https://github.com/aleksander-mendoza).

### Changed

* `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.
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ Currently the following learning algorithms with respective target models are su

Algorithm (active) | Target models || Algorithm (passive) | Models
--- | --- | --- | --- | ---
ADT | `Mealy` || RPNI | `DFA` `Mealy`
DHC | `Mealy` || RPNI (EDSM) | `DFA`
Discrimination Tree | `DFA` `Mealy` `VPDA` || RPNI (MDL) | `DFA`
Kearns & Vazirani | `DFA` `Mealy`
ADT | `Mealy` || OSTIA | `SST`
DHC | `Mealy` || RPNI | `DFA`
Discrimination Tree | `DFA` `Mealy` `VPDA` || RPNI (EDSM) | `DFA`
Kearns & Vazirani | `DFA` `Mealy` || RPNI (MDL) | `DFA`
L* (incl. variants) | `DFA` `Mealy`
NL* | `NFA`
TTT | `DFA` `Mealy` `VPDA`
Expand Down
88 changes: 88 additions & 0 deletions algorithms/passive/ostia/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2013-2020 TU Dortmund
This file is part of LearnLib, http://www.learnlib.de/.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<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">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>de.learnlib</groupId>
<artifactId>learnlib-algorithms-passive-parent</artifactId>
<version>0.17.0-SNAPSHOT</version>
</parent>

<artifactId>learnlib-ostia</artifactId>

<name>LearnLib :: Algorithms :: OSTIA</name>
<description>The OSTIA passive learning algorithm</description>

<dependencies>
<dependency>
<groupId>de.learnlib</groupId>
<artifactId>learnlib-api</artifactId>
</dependency>

<dependency>
<groupId>net.automatalib</groupId>
<artifactId>automata-api</artifactId>
</dependency>
<dependency>
<groupId>net.automatalib</groupId>
<artifactId>automata-commons-smartcollections</artifactId>
</dependency>
<dependency>
<groupId>net.automatalib</groupId>
<artifactId>automata-commons-util</artifactId>
</dependency>
<dependency>
<groupId>net.automatalib</groupId>
<artifactId>automata-core</artifactId>
</dependency>

<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
</dependency>

<!-- test -->
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>de.learnlib.testsupport</groupId>
<artifactId>learnlib-learner-it-support</artifactId>
</dependency>

<dependency>
<groupId>net.automatalib</groupId>
<artifactId>automata-serialization-dot</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>net.automatalib</groupId>
<artifactId>automata-util</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/* Copyright (C) 2013-2020 TU Dortmund
* This file is part of LearnLib, http://www.learnlib.de/.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.learnlib.algorithms.ostia;

import org.checkerframework.checker.nullness.qual.Nullable;

/**
* @author Aleksander Mendoza-Drosik
*/
class Blue {

final State parent;
final int symbol;

Blue(State parent, int symbol) {
this.symbol = symbol;
this.parent = parent;
}

@Nullable State state() {
final @Nullable Edge edge = parent.transitions[symbol];
assert edge != null;
return edge.target;
}

@Override
public String toString() {
return String.valueOf(state());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* Copyright (C) 2013-2020 TU Dortmund
* This file is part of LearnLib, http://www.learnlib.de/.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.learnlib.algorithms.ostia;

import org.checkerframework.checker.nullness.qual.Nullable;

/**
* @author Aleksander Mendoza-Drosik
*/
class Edge {

@Nullable IntQueue out;
State target;

Edge() {}

Edge(Edge edge) {
out = IntQueue.copyAndConcat(edge.out, null);
target = edge.target;
}

@Override
public String toString() {
return String.valueOf(target);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* Copyright (C) 2013-2020 TU Dortmund
* This file is part of LearnLib, http://www.learnlib.de/.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package de.learnlib.algorithms.ostia;

import java.util.HashSet;
import java.util.Set;
import java.util.StringJoiner;

import net.automatalib.commons.smartcollections.IntSeq;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.PolyNull;

/**
* @author Aleksander Mendoza-Drosik
*/
class IntQueue {

int value;
@Nullable IntQueue next;

@Override
public String toString() {
final StringJoiner sj = new StringJoiner(", ", "[", "]");

IntQueue iter = this;
while (iter != null) {
sj.add(Integer.toString(iter.value));
iter = iter.next;
}
return sj.toString();
}

static @Nullable IntQueue asQueue(IntSeq str) {
IntQueue q = null;
for (int i = str.size() - 1; i >= 0; i--) {
IntQueue next = new IntQueue();
next.value = str.get(i);
next.next = q;
q = next;
}
assert !IntQueue.hasCycle(q);
return q;
}

static boolean eq(@Nullable IntQueue a, @Nullable IntQueue b) {
IntQueue aIter = a;
IntQueue bIter = b;
while (aIter != null && bIter != null) {
if (aIter.value != bIter.value) {
return false;
}
aIter = aIter.next;
bIter = bIter.next;
}
return aIter == null && bIter == null;
}

static boolean hasCycle(@Nullable IntQueue q) {
final Set<IntQueue> elements = new HashSet<>();
IntQueue iter = q;
while (iter != null) {
if (!elements.add(iter)) {
return true;
}
iter = iter.next;
}
return false;
}

static @PolyNull IntQueue copyAndConcat(@Nullable IntQueue q, @PolyNull IntQueue tail) {
assert !hasCycle(q) && !hasCycle(tail);
if (q == null) {
return tail;
}
final IntQueue root = new IntQueue();
root.value = q.value;
IntQueue curr = root;
IntQueue iter = q.next;
while (iter != null) {
curr.next = new IntQueue();
curr = curr.next;
curr.value = iter.value;
iter = iter.next;
}
curr.next = tail;
assert !hasCycle(root);
return root;
}
}
Loading