static void runTransformedLearner(boolean withCache) {

        // setup SULs and counters
        StateLocalInputSUL<Integer, Character> target = SUL;

        ResetCounterStateLocalInputSUL<Integer, Character> resetCounter =
                new ResetCounterStateLocalInputSUL<>("Resets", target);
        SymbolCounterStateLocalInputSUL<Integer, Character> symbolCounter =
                new SymbolCounterStateLocalInputSUL<>("Symbols", resetCounter);

        // construct a (regular) simulator membership query oracle
        MealyMembershipOracle<Integer, OutputAndLocalInputs<Integer, Character>> mqOracle =
                new StateLocalInputSULOracle<>(symbolCounter);

        // construct storage for EquivalenceOracle chain, because we want to use the potential cache as well
        List<MealyEquivalenceOracle<Integer, OutputAndLocalInputs<Integer, Character>>> eqOracles = new ArrayList<>(2);

        if (withCache) {
            MealyCacheOracle<Integer, OutputAndLocalInputs<Integer, Character>> mqCache =
                    MealyCaches.createStateLocalInputTreeCache(INPUTS, mqOracle);
            eqOracles.add(mqCache.createCacheConsistencyTest());
            mqOracle = mqCache;
        }

        // construct L* instance
        ExtensibleLStarMealy<Integer, OutputAndLocalInputs<Integer, Character>> lstar =
                new ExtensibleLStarMealyBuilder<Integer, OutputAndLocalInputs<Integer, Character>>().withAlphabet(INPUTS)
                                                                                                    .withOracle(mqOracle)
                                                                                                    .withCexHandler(
                                                                                                            ObservationTableCEXHandlers.RIVEST_SCHAPIRE)
                                                                                                    .create();

        // here, we simply fallback to an equivalence check for the transformed automaton model
        eqOracles.add(new MealySimulatorEQOracle<>(TRANSFORMED_TARGET));

        // construct single EQ oracle
        MealyEquivalenceOracle<Integer, OutputAndLocalInputs<Integer, Character>> eqOracle =
                new MealyEQOracleChain<>(eqOracles);

        // construct the experiment
        MealyExperiment<Integer, OutputAndLocalInputs<Integer, Character>> experiment =
                new MealyExperiment<>(lstar, eqOracle, INPUTS);

        // run experiment
        experiment.run();

        // report results
        System.out.println("Transformed Hypothesis" + (withCache ? ", with cache" : ""));
        System.out.println("-------------------------------------------------------");

        System.out.println(resetCounter.getStatisticalData().getSummary());
        System.out.println(symbolCounter.getStatisticalData().getSummary());

        System.out.println("-------------------------------------------------------");
    }
static void runTransformedLearner ( boolean withCache ) { StateLocalInputSUL < Integer , Character > target = SUL ; ResetCounterStateLocalInputSUL < Integer , Character > resetCounter = new ResetCounterStateLocalInputSUL < > ( "Resets" , target ) ; SymbolCounterStateLocalInputSUL < Integer , Character > symbolCounter = new SymbolCounterStateLocalInputSUL < > ( "Symbols" , resetCounter ) ; MealyMembershipOracle < Integer , OutputAndLocalInputs < Integer , Character > > mqOracle = new StateLocalInputSULOracle < > ( symbolCounter ) ; List < MealyEquivalenceOracle < Integer , OutputAndLocalInputs < Integer , Character > > > eqOracles = new ArrayList < > ( 2 ) ; if ( withCache ) { MealyCacheOracle < Integer , OutputAndLocalInputs < Integer , Character > > mqCache = MealyCaches . createStateLocalInputTreeCache ( INPUTS , mqOracle ) ; eqOracles . add ( mqCache . createCacheConsistencyTest ( ) ) ; mqOracle = mqCache ; } ExtensibleLStarMealy < Integer , OutputAndLocalInputs < Integer , Character > > lstar = new ExtensibleLStarMealyBuilder < Integer , OutputAndLocalInputs < Integer , Character > > ( ) . withAlphabet ( INPUTS ) . withOracle ( mqOracle ) . withCexHandler ( ObservationTableCEXHandlers . RIVEST_SCHAPIRE ) . create ( ) ; eqOracles . add ( new MealySimulatorEQOracle < > ( TRANSFORMED_TARGET ) ) ; MealyEquivalenceOracle < Integer , OutputAndLocalInputs < Integer , Character > > eqOracle = new MealyEQOracleChain < > ( eqOracles ) ; MealyExperiment < Integer , OutputAndLocalInputs < Integer , Character > > experiment = new MealyExperiment < > ( lstar , eqOracle , INPUTS ) ; experiment . run ( ) ; System . out . println ( "Transformed Hypothesis" + ( withCache ? ", with cache" : "" ) ) ; System . out . println ( "-------------------------------------------------------" ) ; System . out . println ( resetCounter . getStatisticalData ( ) . getSummary ( ) ) ; System . out . println ( symbolCounter . getStatisticalData ( ) . getSummary ( ) ) ; System . out . println ( "-------------------------------------------------------" ) ; }
Uses the raw {@link StateLocalInputSUL} to infer a complete partial {@link MealyMachine} as in classical automata
learning. Note: here the {@link MealyMembershipOracle} needs to take care of mapping potentially undefined inputs
of the system under learning to processable outputs for the learner.