Skip to content

Commit

Permalink
refactor Mapper interface and add semantic refinements
Browse files Browse the repository at this point in the history
- moved #pre and #post methods from the SULMapper to the generic Mapper interface
  to allow implementing stateful (generic) mappers.
- added {A,}SynchronuousMapper markup interfaces for refining the contract whether
  the Mapper is utilized in per-symbol transformation manner or in a per-query
  way.
  • Loading branch information
mtf90 committed Dec 5, 2017
1 parent e4a18ae commit adc2d1a
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 34 deletions.
55 changes: 55 additions & 0 deletions api/src/main/java/de/learnlib/api/Mapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@
*/
public interface Mapper<AI, AO, CI, CO> {

/**
* Method that is invoked before any translation steps on a word are performed. Usually left un-implemented for
* stateless mappers.
*/
default void pre() {}

/**
* Method that is invoked after all translation steps on a word are performed. Usually left un-implemented for
* stateless mappers.
*/
default void post() {}

/**
* Method that maps an abstract input to a corresponding concrete input.
*
Expand All @@ -57,4 +69,47 @@ public interface Mapper<AI, AO, CI, CO> {
* @return the abstract output
*/
AO mapOutput(CO concreteOutput);

/**
* A mapper refinement to establish the contract of a synchronized, symbol-wise translation of input words for
* reactive systems. This means, after each call to {@link #mapInput(Object)} the next call on {@code this} object
* will be {@link #mapOutput(Object)} which is passed the immediate answer to the previously mapped input.
*
* @param <AI>
* abstract input symbol type.
* @param <AO>
* abstract output symbol type.
* @param <CI>
* concrete input symbol type.
* @param <CO>
* concrete output symbol type.
*
* @author frohme
* @see AsynchronousMapper
*/
interface SynchronousMapper<AI, AO, CI, CO> extends Mapper<AI, AO, CI, CO> {}

/**
* A mapper refinement to establish the contract of a asynchronous, query-wise translation of input words. This
* means, for a sequence of input symbols, {@link #mapInput(Object)} may be called multiple times before any call to
* {@link #mapOutput(Object)} occurs.
* <p>
* Especially in the context of translating {@link de.learnlib.api.query.Query queries} for mealy machines, which
* support the concept of un-answered prefixes (combined with answered suffixes) this means, the number of {@link
* #mapInput(Object)} invocations may be larger than the size of the output word passed to the {@link
* #mapOutput(Object)} function.
*
* @param <AI>
* abstract input symbol type.
* @param <AO>
* abstract output symbol type.
* @param <CI>
* concrete input symbol type.
* @param <CO>
* concrete output symbol type.
*
* @author frohme
* @see SynchronousMapper
*/
interface AsynchronousMapper<AI, AO, CI, CO> extends Mapper<AI, AO, CI, CO> {}
}
13 changes: 2 additions & 11 deletions drivers/mapper/src/main/java/de/learnlib/mapper/api/SULMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import javax.annotation.Nonnull;

import de.learnlib.api.Mapper;
import de.learnlib.api.Mapper.SynchronousMapper;
import de.learnlib.api.SUL;
import de.learnlib.api.exception.SULException;
import de.learnlib.mapper.SULMappers;
Expand Down Expand Up @@ -49,17 +50,7 @@
*
* @author Malte Isberner
*/
public interface SULMapper<AI, AO, CI, CO> extends Mapper<AI, AO, CI, CO> {

/**
* Method that is invoked before any translation steps on a word are performed.
*/
void pre();

/**
* Method that is invoked after all translation steps on a word are performed.
*/
void post();
public interface SULMapper<AI, AO, CI, CO> extends SynchronousMapper<AI, AO, CI, CO> {

/**
* Checks whether it is possible to {@link #fork() fork} this mapper.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@
*/
package de.learnlib.oracle.membership;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import de.learnlib.api.Mapper;
import de.learnlib.api.oracle.MembershipOracle;
import de.learnlib.api.query.DefaultQuery;
import de.learnlib.api.query.Query;
import de.learnlib.api.Mapper.AsynchronousMapper;
import de.learnlib.api.oracle.QueryAnswerer;
import de.learnlib.api.oracle.SingleQueryOracle;
import net.automatalib.words.Word;

/**
* A utility class that allows to lift a membership oracle of concrete input/output symbols to a membership oracle of
Expand All @@ -39,31 +35,26 @@
*
* @author frohme
*/
public class MappedOracle<AI, AO, CI, CO> implements MembershipOracle<AI, AO> {
public class MappedOracle<AI, AO, CI, CO> implements SingleQueryOracle<AI, AO> {

private final MembershipOracle<CI, CO> delegate;
private final QueryAnswerer<CI, CO> delegate;

private final Mapper<AI, AO, CI, CO> mapper;
private final AsynchronousMapper<AI, AO, CI, CO> mapper;

public MappedOracle(MembershipOracle<CI, CO> delegate, Mapper<AI, AO, CI, CO> mapper) {
public MappedOracle(QueryAnswerer<CI, CO> delegate, AsynchronousMapper<AI, AO, CI, CO> mapper) {
this.delegate = delegate;
this.mapper = mapper;
}

@Override
public void processQueries(Collection<? extends Query<AI, AO>> queries) {
final List<Query<AI, AO>> orderedQueries = new ArrayList<>(queries);
final List<DefaultQuery<CI, CO>> mappedQueries = new ArrayList<>(queries.size());
public AO answerQuery(Word<AI> prefix, Word<AI> suffix) {
mapper.pre();

for (final Query<AI, AO> q : orderedQueries) {
mappedQueries.add(new DefaultQuery<>(q.getPrefix().transform(mapper::mapInput),
q.getSuffix().transform(mapper::mapInput)));
}
final CO output = delegate.answerQuery(prefix.transform(mapper::mapInput), suffix.transform(mapper::mapInput));
final AO result = mapper.mapOutput(output);

this.delegate.processQueries(mappedQueries);
mapper.post();

for (int i = 0; i < orderedQueries.size(); i++) {
orderedQueries.get(i).answer(mapper.mapOutput(mappedQueries.get(i).getOutput()));
}
return result;
}
}

0 comments on commit adc2d1a

Please sign in to comment.