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

net.automatalib.modelchecker.ltsmin.LTSminDFA Maven / Gradle / Ivy

/* Copyright (C) 2013-2023 TU Dortmund
 * This file is part of AutomataLib, http://www.automatalib.net/.
 *
 * 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 net.automatalib.modelchecker.ltsmin;

import java.io.File;
import java.io.IOException;
import java.util.Collection;

import net.automatalib.alphabet.Alphabet;
import net.automatalib.alphabet.Alphabets;
import net.automatalib.automaton.fsa.CompactDFA;
import net.automatalib.automaton.fsa.DFA;
import net.automatalib.automaton.fsa.MutableDFA;
import net.automatalib.exception.ModelCheckingException;
import net.automatalib.modelchecking.ModelChecker;
import net.automatalib.serialization.etf.writer.DFA2ETFWriter;
import net.automatalib.util.automaton.copy.AutomatonCopyMethod;
import net.automatalib.util.automaton.copy.AutomatonLowLevelCopy;
import net.automatalib.util.automaton.fsa.DFAs;

/**
 * A model checker using LTSmin for DFAs.
 * 

* An important feature of this {@link DFAModelChecker}, is that it will check if a given DFA hypothesis is * prefix-closed. *

* Another important feature is that rejecting states are NOT part of the LTS. This avoids the need for an unconditional * fairness constraint in LTL formulae. * * @param * the input type. * @param * the type of counterexample * * @see DFAs#isPrefixClosed(DFA, Collection) */ public interface LTSminDFA extends LTSmin, R>, ModelChecker.DFAModelChecker { /** * The index in the FSM state vector for accept/reject. */ String LABEL_NAME = "label"; /** * The value in the state vector for acceptance. */ String LABEL_VALUE = "accept"; @Override default void automaton2ETF(DFA automaton, Collection inputs, File etf) throws IOException { dfa2ETF(automaton, inputs, etf); } /** * Writes the given {@code dfa} to {@code etf}, while skipping rejecting states. * * @param dfa * the DFA to write. * @param inputs * the alphabet. * @param etf * the file to write to. * @param * the state type * * @throws IOException * if the dfa couldn't be written to the provided file. * @throws ModelCheckingException * if the dfa cannot be transformed into a valid LTS. */ default void dfa2ETF(DFA dfa, Collection inputs, File etf) throws IOException { // check that the DFA rejects the empty language if (DFAs.acceptsEmptyLanguage(dfa)) { throw new ModelCheckingException("DFA accepts the empty language, the LTS for such a DFA is not defined."); } final Alphabet alphabet = Alphabets.fromCollection(inputs); // check the DFA is prefix-closed if (!DFAs.isPrefixClosed(dfa, alphabet)) { throw new ModelCheckingException("DFA is not prefix closed."); } // remove all rejecting states final MutableDFA copy = new CompactDFA<>(alphabet, dfa.size()); AutomatonLowLevelCopy.copy(AutomatonCopyMethod.STATE_BY_STATE, dfa, inputs, copy, dfa::isAccepting, (s, i, t) -> true); DFA2ETFWriter.getInstance().writeModel(etf, copy, alphabet); } }