public ThreadResult call() throws Exception
{
final int alphabet = 2*states;
LearnerGraph referenceGraph = null;
ThreadResult outcome = new ThreadResult();
Label uniqueFromInitial = null;
final boolean pickUniqueFromInitial = true;
MachineGenerator mg = new MachineGenerator(states, 400 , (int)Math.round((double)states/5));mg.setGenerateConnected(true);
do
{
referenceGraph = mg.nextMachine(alphabet,seed, config, converter).pathroutines.buildDeterministicGraph();// reference graph has no reject-states, because we assume that undefined transitions lead to reject states.
if (pickUniqueFromInitial)
{
Map<Label,CmpVertex> uniques = PairQualityLearner.uniqueFromState(referenceGraph);
if(!uniques.isEmpty())
{
// some uniques are loops, hence eliminate them to match our case study
for(Entry<Label,CmpVertex> entry:uniques.entrySet())
if (referenceGraph.transitionMatrix.get(entry.getValue()).get(entry.getKey()) != entry.getValue())
{
referenceGraph.setInit(entry.getValue());uniqueFromInitial = entry.getKey();break;// found a unique of interest
}
}
}
}
while(pickUniqueFromInitial && uniqueFromInitial == null);
LearnerEvaluationConfiguration learnerEval = new LearnerEvaluationConfiguration(config);learnerEval.setLabelConverter(converter);
final Collection<List<Label>> testSet = PaperUAS.computeEvaluationSet(referenceGraph,states*3,states*alphabet);
for(int attempt=0;attempt<3;++attempt)
{// try learning the same machine a few times
LearnerGraph pta = new LearnerGraph(config);
RandomPathGenerator generator = new RandomPathGenerator(referenceGraph,new Random(attempt),5,referenceGraph.getVertex(Arrays.asList(new Label[]{uniqueFromInitial})));
generator.setWalksShouldLeadToInitialState();
// test sequences will be distributed around
final int pathLength = generator.getPathLength();
final int sequencesPerChunk = PairQualityLearner.makeEven(alphabet*states*traceQuantity);// we are only using one chunk here but the name is unchanged.
// Usually, the total number of elements in test sequences (alphabet*states*traceQuantity) will be distributed around (random(pathLength)+1). The total size of PTA is a product of these two.
// For the purpose of generating long traces, we construct as many traces as there are states but these traces have to be rather long,
// that is, length of traces will be (random(pathLength)+1)*sequencesPerChunk/states and the number of traces generated will be the same as the number of states.
final int tracesToGenerate = 20;//PairQualityLearner.makeEven(states*traceQuantity*3);
final Random rnd = new Random(seed*31+attempt);
generator.generateRandomPosNeg(tracesToGenerate, 1, false, new RandomLengthGenerator() {
@Override
public int getLength() {
return 6;//10*(rnd.nextInt(pathLength)+1)*sequencesPerChunk/tracesToGenerate;
}
@Override
public int getPrefixLength(int len) {
return len;
}
},true,true,null,Arrays.asList(new Label[]{uniqueFromInitial}));
//System.out.println(generator.getAllSequences(0).getData(PTASequenceEngine.truePred));
/*
for(List<Label> seq:referenceGraph.wmethod.computeNewTestSet(1))
{
pta.paths.augmentPTA(seq, referenceGraph.getVertex(seq) != null, false, null);
}*/
//pta.paths.augmentPTA(referenceGraph.wmethod.computeNewTestSet(referenceGraph.getInit(),1));// this one will not set any states as rejects because it uses shouldbereturned
//referenceGraph.pathroutines.completeGraph(referenceGraph.nextID(false));
if (onlyUsePositives)
pta.paths.augmentPTA(generator.getAllSequences(0).filter(new FilterPredicate() {
@Override
public boolean shouldBeReturned(Object name) {
return ((statechum.analysis.learning.rpnicore.RandomPathGenerator.StateName)name).accept;
}
}));
else
pta.paths.augmentPTA(generator.getAllSequences(0));// the PTA will have very few reject-states because we are generating few sequences and hence there will be few negative sequences.
// In order to approximate the behaviour of our case study, we need to compute which pairs are not allowed from a reference graph and use those as if-then automata to start the inference.
/*
synchronized (AbstractLearnerGraph.syncObj) {
PaperUAS.computePTASize(selectionID+" with unique "+uniqueFromInitial+" : ", pta, referenceGraph);
}*/
//Visualiser.updateFrame(referenceGraph, pta);
//Visualiser.waitForKey();
pta.clearColours();
if (!onlyUsePositives)
{
assert pta.getStateNumber() > pta.getAcceptStateNumber() : "graph with only accept states but onlyUsePositives is not set";
Map<Label,Set<Label>> infeasiblePairs = PairQualityLearner.computeInfeasiblePairs(referenceGraph);
Map<Label,Set<Label>> subsetOfPairs = new TreeMap<Label,Set<Label>>();
for(Entry<Label,Set<Label>> entry:infeasiblePairs.entrySet())
{
Set<Label> value = new TreeSet<Label>();
if (!entry.getValue().isEmpty())
{
Label possibleLabels[]=entry.getValue().toArray(new Label[]{});
if (possibleLabels.length == 1)
value.add(possibleLabels[0]);
else
value.add(possibleLabels[rnd.nextInt(possibleLabels.length)]);
}