
de.learnlib.algorithm.lstar.ce.ObservationTableCEXHandlers Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of learnlib-lstar Show documentation
Show all versions of learnlib-lstar Show documentation
This artifact provides the implementation of the L* learning algorithm described in the paper "Learning Regular
Sets from Queries and Counterexamples" (https://doi.org/10.1016/0890-5401(87)90052-6) by Dana Angluin including
variations and optimizations thereof such as the versions based on "On the Learnability of Infinitary Regular
Sets" (https://dx.doi.org/10.1006/inco.1995.1070) by Oded Maler and Amir Pnueli or "Inference of finite automata
using homing sequences" (http://dx.doi.org/10.1006/inco.1993.1021) by Ronald L. Rivest and Robert E. Schapire.
The newest version!
/* Copyright (C) 2013-2023 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.algorithm.lstar.ce;
import java.util.Collections;
import java.util.List;
import de.learnlib.counterexample.GlobalSuffixFinder;
import de.learnlib.counterexample.GlobalSuffixFinders;
import de.learnlib.counterexample.LocalSuffixFinder;
import de.learnlib.counterexample.LocalSuffixFinders;
import de.learnlib.datastructure.observationtable.MutableObservationTable;
import de.learnlib.datastructure.observationtable.Row;
import de.learnlib.oracle.MembershipOracle;
import de.learnlib.query.DefaultQuery;
import de.learnlib.query.Query;
import net.automatalib.automaton.concept.SuffixOutput;
import net.automatalib.word.Word;
import org.checkerframework.checker.nullness.qual.Nullable;
public final class ObservationTableCEXHandlers {
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> CLASSIC_LSTAR =
new ObservationTableCEXHandler<@Nullable Object, @Nullable Object>() {
@Override
public List>> handleCounterexample(DefaultQuery ceQuery,
MutableObservationTable table,
SuffixOutput hypOutput,
MembershipOracle oracle) {
return handleClassicLStar(ceQuery, table, oracle);
}
@Override
public boolean needsConsistencyCheck() {
return true;
}
@Override
public String toString() {
return "ClassicLStar";
}
};
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> SUFFIX1BY1 =
new ObservationTableCEXHandler<@Nullable Object, @Nullable Object>() {
@Override
public List>> handleCounterexample(DefaultQuery ceQuery,
MutableObservationTable table,
SuffixOutput hypOutput,
MembershipOracle oracle) {
return handleSuffix1by1(ceQuery, table, oracle);
}
@Override
public boolean needsConsistencyCheck() {
return false;
}
@Override
public String toString() {
return "Suffix1by1";
}
};
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> MALER_PNUELI =
fromGlobalSuffixFinder(GlobalSuffixFinders.MALER_PNUELI);
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> SHAHBAZ =
fromGlobalSuffixFinder(GlobalSuffixFinders.SHAHBAZ);
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> FIND_LINEAR =
fromLocalSuffixFinder(LocalSuffixFinders.FIND_LINEAR, false);
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> FIND_LINEAR_ALLSUFFIXES =
fromLocalSuffixFinder(LocalSuffixFinders.FIND_LINEAR, true);
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> FIND_LINEAR_REVERSE =
fromLocalSuffixFinder(LocalSuffixFinders.FIND_LINEAR_REVERSE, false);
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> FIND_LINEAR_REVERSE_ALLSUFFIXES =
fromLocalSuffixFinder(LocalSuffixFinders.FIND_LINEAR_REVERSE, true);
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> RIVEST_SCHAPIRE =
fromLocalSuffixFinder(LocalSuffixFinders.RIVEST_SCHAPIRE, false);
public static final ObservationTableCEXHandler<@Nullable Object, @Nullable Object> RIVEST_SCHAPIRE_ALLSUFFIXES =
fromLocalSuffixFinder(LocalSuffixFinders.RIVEST_SCHAPIRE, true);
private ObservationTableCEXHandlers() {
// prevent instantiation
}
public static ObservationTableCEXHandler fromGlobalSuffixFinder(GlobalSuffixFinder globalFinder) {
return new ObservationTableCEXHandler() {
@Override
public List>> handleCounterexample(DefaultQuery ceQuery,
MutableObservationTable table,
SuffixOutput hypOutput,
MembershipOracle oracle) {
List> suffixes = globalFinder.findSuffixes(ceQuery, table, hypOutput, oracle);
return handleGlobalSuffixes(table, suffixes, oracle);
}
@Override
public boolean needsConsistencyCheck() {
return false;
}
@Override
public String toString() {
return globalFinder.toString();
}
};
}
public static List>> handleGlobalSuffixes(MutableObservationTable table,
List extends Word> suffixes,
MembershipOracle oracle) {
return table.addSuffixes(suffixes, oracle);
}
public static ObservationTableCEXHandler fromLocalSuffixFinder(LocalSuffixFinder localFinder) {
return fromLocalSuffixFinder(localFinder, false);
}
public static ObservationTableCEXHandler fromLocalSuffixFinder(LocalSuffixFinder localFinder,
boolean allSuffixes) {
return new ObservationTableCEXHandler() {
@Override
public List>> handleCounterexample(DefaultQuery ceQuery,
MutableObservationTable table,
SuffixOutput hypOutput,
MembershipOracle oracle) {
int suffixIdx = localFinder.findSuffixIndex(ceQuery, table, hypOutput, oracle);
return handleLocalSuffix(ceQuery, table, suffixIdx, allSuffixes, oracle);
}
@Override
public boolean needsConsistencyCheck() {
return false;
}
@Override
public String toString() {
return localFinder.toString();
}
};
}
public static List>> handleLocalSuffix(Query ceQuery,
MutableObservationTable table,
int suffixIndex,
MembershipOracle oracle) {
return handleLocalSuffix(ceQuery, table, suffixIndex, false, oracle);
}
public static List>> handleLocalSuffix(Query ceQuery,
MutableObservationTable table,
int suffixIndex,
boolean allSuffixes,
MembershipOracle oracle) {
List> suffixes = GlobalSuffixFinders.suffixesForLocalOutput(ceQuery, suffixIndex, allSuffixes);
return handleGlobalSuffixes(table, suffixes, oracle);
}
public static List>> handleClassicLStar(DefaultQuery ceQuery,
MutableObservationTable table,
MembershipOracle oracle) {
List> prefixes = ceQuery.getInput().prefixes(false);
return table.addShortPrefixes(prefixes, oracle);
}
public static List>> handleSuffix1by1(DefaultQuery ceQuery,
MutableObservationTable table,
MembershipOracle oracle) {
List>> unclosed = Collections.emptyList();
Word ceWord = ceQuery.getInput();
int ceLen = ceWord.length();
for (int i = 1; i <= ceLen; i++) {
Word suffix = ceWord.suffix(i);
unclosed = table.addSuffix(suffix, oracle);
if (!unclosed.isEmpty()) {
break;
}
}
return unclosed;
}
@SuppressWarnings("unchecked")
public static ObservationTableCEXHandler<@Nullable Object, @Nullable Object>[] values() {
return new ObservationTableCEXHandler[] {CLASSIC_LSTAR,
SUFFIX1BY1,
MALER_PNUELI,
SHAHBAZ,
FIND_LINEAR,
FIND_LINEAR_ALLSUFFIXES,
FIND_LINEAR_REVERSE,
FIND_LINEAR_REVERSE_ALLSUFFIXES,
RIVEST_SCHAPIRE,
RIVEST_SCHAPIRE_ALLSUFFIXES};
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy