Skip to content

Instantly share code, notes, and snippets.

@mtf90
Created September 12, 2020 22:16
Show Gist options
  • Save mtf90/c4e2cafecf2fbeca1cbbda79a033652c to your computer and use it in GitHub Desktop.
Save mtf90/c4e2cafecf2fbeca1cbbda79a033652c to your computer and use it in GitHub Desktop.
A small example for nesting multiple MQ and EQ oracles
package de.learnlib.examples;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import de.learnlib.api.SUL;
import de.learnlib.api.oracle.EquivalenceOracle.MealyEquivalenceOracle;
import de.learnlib.api.oracle.MembershipOracle.MealyMembershipOracle;
import de.learnlib.api.query.Query;
import de.learnlib.driver.util.MealySimulatorSUL;
import de.learnlib.filter.cache.mealy.MealyCacheConsistencyTest;
import de.learnlib.filter.cache.mealy.MealyCacheOracle;
import de.learnlib.filter.cache.mealy.MealyCaches;
import de.learnlib.oracle.equivalence.MealyEQOracleChain;
import de.learnlib.oracle.equivalence.MealyRandomWordsEQOracle;
import de.learnlib.oracle.membership.SULOracle;
import net.automatalib.automata.transducers.impl.compact.CompactMealy;
import net.automatalib.util.automata.builders.AutomatonBuilders;
import net.automatalib.words.Alphabet;
import net.automatalib.words.Word;
import net.automatalib.words.impl.Alphabets;
public class OracleChainExample {
private final static Alphabet<Integer> INPUTS = Alphabets.integers(0, 1);
private final static int MAX_EQ_LENGTH = 100;
private final static int MAX_EQ_TRIES = 1000;
private final static int MAX_MQ_TRIES = 10;
private final static int MIN_EQ_LENGTH = 10;
private final static Random RANDOM = new Random(42);
public static void main(String[] args) {
final SUL<Integer, Character> sul = constructSUL();
final MealyMembershipOracle<Integer, Character> sulAsOracle = new SULOracle<>(sul);
final MealyMembershipOracle<Integer, Character> probabilisticOracle = new ProbabilisticOracle<>(sulAsOracle);
final MealyCacheOracle<Integer, Character> cacheOracle =
MealyCaches.createTreeCache(INPUTS, probabilisticOracle);
final MealyCacheConsistencyTest<Integer, Character> consistencyTest = cacheOracle.createCacheConsistencyTest();
final MealyEquivalenceOracle<Integer, Character> randomWordOracle =
new MealyRandomWordsEQOracle<>(cacheOracle, MIN_EQ_LENGTH, MAX_EQ_LENGTH, MAX_EQ_TRIES, RANDOM);
final MealyEQOracleChain<Integer, Character> eqOracle =
new MealyEQOracleChain<>(consistencyTest, randomWordOracle);
// setup learner with cacheOracle and eqOracle ...
}
private static class ProbabilisticOracle<I, O> implements MealyMembershipOracle<I, O> {
private final MealyMembershipOracle<I, O> delegate;
public ProbabilisticOracle(MealyMembershipOracle<I, O> delegate) {
this.delegate = delegate;
}
@Override
public void processQueries(Collection<? extends Query<I, Word<O>>> queries) {
final List<Word<O>> outputs = new ArrayList<>(MAX_MQ_TRIES);
for (Query<I, Word<O>> query : queries) {
outputs.clear();
for (int i = 0; i < MAX_MQ_TRIES; i++) {
outputs.add(delegate.answerQuery(query.getPrefix(), query.getSuffix()));
}
//query.answer(majorityVote(outputs));
}
}
}
private static SUL<Integer, Character> constructSUL() {
// just use some random Mealy machine as SUL
// @formatter:off
final CompactMealy<Integer, Character> mealy = AutomatonBuilders.<Integer, Character>newMealy(INPUTS)
.withInitial("s0")
.from("s0")
.on(0).withOutput('a').to("s2")
.on(1).withOutput('b').to("s1")
.from("s1")
.on(0).withOutput('b').loop()
.on(1).withOutput('a').loop()
.from("s2")
.on(0).withOutput('b').loop()
.on(1).withOutput('a').to("s3")
.from("s3")
.on(0).withOutput('a').to("s1")
.create();
// @formatter:on
return new MealySimulatorSUL<>(mealy);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment