All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.learnlib.algorithms.lstar.ce.ObservationTableCEXHandlers Maven / Gradle / Ivy

Go to download

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.

There is a newer version: 0.17.0
Show newest version
/* Copyright (C) 2013-2018 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.lstar.ce;

import java.util.Collections;
import java.util.List;

import de.learnlib.api.oracle.MembershipOracle;
import de.learnlib.api.query.DefaultQuery;
import de.learnlib.api.query.Query;
import de.learnlib.counterexamples.GlobalSuffixFinder;
import de.learnlib.counterexamples.GlobalSuffixFinders;
import de.learnlib.counterexamples.LocalSuffixFinder;
import de.learnlib.counterexamples.LocalSuffixFinders;
import de.learnlib.datastructure.observationtable.MutableObservationTable;
import de.learnlib.datastructure.observationtable.Row;
import net.automatalib.automata.concepts.SuffixOutput;
import net.automatalib.words.Word;

public final class ObservationTableCEXHandlers {

    public static final ObservationTableCEXHandler CLASSIC_LSTAR =
            new ObservationTableCEXHandler() {

                @Override
                public  List>> handleCounterexample(DefaultQuery ceQuery,
                                                                         MutableObservationTable table,
                                                                         SuffixOutput hypOutput,
                                                                         MembershipOracle oracle) {
                    return handleClassicLStar(ceQuery, table, oracle);
                }

                @Override
                public String toString() {
                    return "ClassicLStar";
                }

                @Override
                public boolean needsConsistencyCheck() {
                    return true;
                }

            };

    public static final ObservationTableCEXHandler SUFFIX1BY1 =
            new ObservationTableCEXHandler() {

                @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 MALER_PNUELI =
            fromGlobalSuffixFinder(GlobalSuffixFinders.MALER_PNUELI);

    public static final ObservationTableCEXHandler SHAHBAZ =
            fromGlobalSuffixFinder(GlobalSuffixFinders.SHAHBAZ);

    public static final ObservationTableCEXHandler FIND_LINEAR =
            fromLocalSuffixFinder(LocalSuffixFinders.FIND_LINEAR, false);

    public static final ObservationTableCEXHandler FIND_LINEAR_ALLSUFFIXES =
            fromLocalSuffixFinder(LocalSuffixFinders.FIND_LINEAR, true);

    public static final ObservationTableCEXHandler FIND_LINEAR_REVERSE =
            fromLocalSuffixFinder(LocalSuffixFinders.FIND_LINEAR_REVERSE, false);

    public static final ObservationTableCEXHandler FIND_LINEAR_REVERSE_ALLSUFFIXES =
            fromLocalSuffixFinder(LocalSuffixFinders.FIND_LINEAR_REVERSE, true);

    public static final ObservationTableCEXHandler RIVEST_SCHAPIRE =
            fromLocalSuffixFinder(LocalSuffixFinders.RIVEST_SCHAPIRE, false);

    public static final ObservationTableCEXHandler RIVEST_SCHAPIRE_ALLSUFFIXES =
            fromLocalSuffixFinder(LocalSuffixFinders.RIVEST_SCHAPIRE, true);

    private ObservationTableCEXHandlers() {
        // prevent instantiation
    }

    public static  ObservationTableCEXHandler fromGlobalSuffixFinder(final 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> suffixes,
                                                                 MembershipOracle oracle) {
        return table.addSuffixes(suffixes, oracle);
    }

    public static  ObservationTableCEXHandler fromLocalSuffixFinder(final LocalSuffixFinder localFinder) {
        return fromLocalSuffixFinder(localFinder, false);
    }

    public static  ObservationTableCEXHandler fromLocalSuffixFinder(final LocalSuffixFinder localFinder,
                                                                                final 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[] 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};
    }
}