{
OtpErlangObject outcome = null;
try
{
final AtomicLong counter = new AtomicLong();
RPNIUniversalLearner learner = new RPNIUniversalLearner(null, learnerInitConfiguration) {
@Override
public Stack<PairScore> ChooseStatePairs(LearnerGraph graph)
{
// send the notification if necessary
if (message.arity() > 2 && message.elementAt(2) instanceof OtpErlangPid)
sendProgress((OtpErlangPid)message.elementAt(2), ref, graph, null, counter);
// check if we were asked to terminate
try {
OtpErlangObject messageReceived = mbox.receive(0);// do not wait, return null if anything received
if (messageReceived != null && messageReceived instanceof OtpErlangTuple && ((OtpErlangTuple)messageReceived).arity() == 2)
{
OtpErlangTuple cmd = ((OtpErlangTuple)messageReceived);
if (cmd.elementAt(0).equals(ref) && cmd.elementAt(1).equals(msgStop))
throw new AskedToTerminateException();
}
} catch (OtpErlangExit e) {
Helper.throwUnchecked("node exited", e);
} catch (OtpErlangDecodeException e) {
Helper.throwUnchecked("decode exception", e);
}
// resume learning.
return super.ChooseStatePairs(graph);
}
@Override
public Pair<Integer, String> CheckWithEndUser(
LearnerGraph model,
List<Label> question,
int expectedForNoRestart,
List<Boolean> consistentFacts,
PairScore pairBeingMerged,
Object[] moreOptions) {
return super.CheckWithEndUser(model, question, expectedForNoRestart,
consistentFacts, pairBeingMerged, moreOptions);
}
};
learner.init(sPlus, sMinus);
if (learnerInitConfiguration.graph != null)
{
learnerInitConfiguration.graph.clearColours();learnerInitConfiguration.graph.getInit().setColour(JUConstants.RED);
LearnerGraph.copyGraphs(learnerInitConfiguration.graph,learner.getTentativeAutomaton());
}
LearnerGraph graphLearnt = learner.learnMachine();
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgOk, constructFSM(graphLearnt)});
}
catch(AskedToTerminateException e)
{
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgTerminate});
}
catch(Throwable ex)
{
ex.printStackTrace();
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgFailure,new OtpErlangList(ex.getMessage())});
}
mbox.send(erlangPartner,outcome);
}
else
// Args: Ref,learn, pid
// pid is optional, where provided, progress messages are reported in a form of {Ref,'status',step}
// in the course of learning, the learner is receptive to messages directed at its normal PID, a {Ref,terminate} command will kill it and the response will be {Ref,terminate}.
// Response: Ref,ok,fsm
// on error: Ref,failure,text_of_the_error (as string)
if (command.equals(msgLearnEDSMMARKOV) && message.arity() >= 2)
{
OtpErlangObject outcome = null;
try
{
final AtomicLong counter = new AtomicLong();
learnerInitConfiguration.config.setLearnerScoreMode(ScoreMode.ONLYOVERRIDE);
LearnerGraph pta=new LearnerGraph(learnerInitConfiguration.config);
for(List<Label> seq:sPlus)
pta.paths.augmentPTA(seq,true,false,null);
for(List<Label> seq:sMinus)
pta.paths.augmentPTA(seq,false,false,null);
final MarkovModel m= new MarkovModel(3,true,true,false);
new MarkovClassifier(m, pta).updateMarkov(false);// construct Markov chain if asked for.
final ConsistencyChecker checker = new MarkovClassifier.DifferentPredictionsInconsistencyNoBlacklistingIncludeMissingPrefixes();
pta.clearColours();
EDSM_MarkovLearner learner = new EDSM_MarkovLearner(learnerInitConfiguration,pta,0) {
@Override
public Stack<PairScore> ChooseStatePairs(LearnerGraph graph)
{
// send the notification if necessary
if (message.arity() > 2 && message.elementAt(2) instanceof OtpErlangPid)
sendProgress((OtpErlangPid)message.elementAt(2), ref, graph, null, counter);
// check if we were asked to terminate
try {
OtpErlangObject messageReceived = mbox.receive(0);// do not wait, return null if anything received
if (messageReceived != null && messageReceived instanceof OtpErlangTuple && ((OtpErlangTuple)messageReceived).arity() == 2)
{
OtpErlangTuple cmd = ((OtpErlangTuple)messageReceived);
if (cmd.elementAt(0).equals(ref) && cmd.elementAt(1).equals(msgStop))
throw new AskedToTerminateException();
}
} catch (OtpErlangExit e) {
Helper.throwUnchecked("node exited", e);
} catch (OtpErlangDecodeException e) {
Helper.throwUnchecked("decode exception", e);
}
// resume learning.
return super.ChooseStatePairs(graph);
}
@Override
public Pair<Integer, String> CheckWithEndUser(
LearnerGraph model,
List<Label> question,
int expectedForNoRestart,
List<Boolean> consistentFacts,
PairScore pairBeingMerged,
Object[] moreOptions) {
return super.CheckWithEndUser(model, question, expectedForNoRestart,
consistentFacts, pairBeingMerged, moreOptions);
}
};
learner.setMarkov(m);learner.setChecker(checker);
learner.setUseNewScoreNearRoot(false);learner.setUseClassifyPairs(false);
learner.setDisableInconsistenciesInMergers(false);
if (learnerInitConfiguration.graph != null)
{
learnerInitConfiguration.graph.clearColours();learnerInitConfiguration.graph.getInit().setColour(JUConstants.RED);
LearnerGraph.copyGraphs(learnerInitConfiguration.graph,learner.getTentativeAutomaton());
}
LearnerGraph graphLearnt = learner.learnMachine(new LinkedList<List<Label>>(),new LinkedList<List<Label>>());
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgOk, constructFSM(graphLearnt)});
}
catch(AskedToTerminateException e)
{
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgTerminate});
}
catch(Throwable ex)
{
ex.printStackTrace();
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgFailure,new OtpErlangList(ex.getMessage())});
}
mbox.send(erlangPartner,outcome);
}
else
// Args: Ref,addTypeInformation,list of pairs containing method names and types.
if (command.equals(msgAddTypeInformation) && message.arity() >= 3)
{
OtpErlangObject outcome = null;
try
{
updateFrom((OtpErlangList)message.elementAt(2), overrides);
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgOk, typeMapToList(overrides)});
}
catch(Throwable ex)
{
ex.printStackTrace();
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgFailure,new OtpErlangList(ex.getMessage())});
}
mbox.send(erlangPartner,outcome);
}
else
// Args: Ref,purgeModuleInformation
// Since using addTypeInformation followed by learnErlang causes changes to the alphabet modules we are dealing with, independence of tests requires the collection of loaded modules to be purged. This is the purpose of this function.
if (command.equals(msgPurgeModuleInformation) && message.arity() >= 2)
{
OtpErlangObject outcome = null;
try
{
ErlangModule.flushRegistry();
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgOk});
}
catch(Throwable ex)
{
ex.printStackTrace();
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgFailure,new OtpErlangList(ex.getMessage())});
}
mbox.send(erlangPartner,outcome);
}
else
// Args: Ref,extractTypeInformation,moduleFileFullPath.
// Returns a list of pairs of method names and types.
if (command.equals(msgExtractTypeInformation) && message.arity() >= 3)
{
OtpErlangObject outcome = null;
try
{
ErlangModule.setupErlangConfiguration(learnerInitConfiguration.config, new File(((OtpErlangAtom)message.elementAt(2)).atomValue()));
// we start a separate Erlang node to run the questions
ErlangRunner erlangRunner = ErlangRuntime.getDefaultRuntime().createNewRunner();
learnerInitConfiguration.config.setErlangMboxName(erlangRunner.getRunnerName());
final ErlangModule mod = ErlangModule.loadModule(learnerInitConfiguration.config);
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgOk, typeMapToList(mod.sigTypes)});
}
catch(Throwable ex)
{
ex.printStackTrace();
outcome = new OtpErlangTuple(new OtpErlangObject[]{ref,msgFailure,new OtpErlangList(ex.getMessage())});
}
mbox.send(erlangPartner,outcome);
}
else
// Args: Ref,learnErlang,moduleFileFullPath, pid
// pid is optional, where provided, progress messages are reported in a form of {Ref,'status',step}
// in the course of learning, the learner is receptive to messages directed at its normal PID, a {Ref,terminate} command will kill it and the response will be {Ref,terminate}.
// Response: Ref,ok,fsm
// on error: Ref,failure,text_of_the_error (as string)
if (command.equals(msgLearnErlang) && message.arity() >= 3)
{
OtpErlangObject outcome = null;
try
{
ErlangModule.setupErlangConfiguration(learnerInitConfiguration.config, new File(((OtpErlangAtom)message.elementAt(2)).atomValue()));
// we start a separate Erlang node to run the questions
ErlangRunner erlangRunner = ErlangRuntime.getDefaultRuntime().createNewRunner();
learnerInitConfiguration.config.setErlangMboxName(erlangRunner.getRunnerName());
final AtomicLong counter = new AtomicLong();
final ErlangModule mod = ErlangModule.loadModule(learnerInitConfiguration.config);
mod.rebuildSigs(learnerInitConfiguration.config, overrides);mod.behaviour.generateAlphabet(learnerInitConfiguration.config);
ErlangOracleLearner learner = new ErlangOracleLearner(null, learnerInitConfiguration) {
@Override
public Stack<PairScore> ChooseStatePairs(LearnerGraph graph)
{
// check if we were asked to terminate
try {
if (message.arity() > 3 && message.elementAt(3) instanceof OtpErlangPid)
// send the notification if necessary
sendProgress((OtpErlangPid)message.elementAt(3), ref, graph, mod, counter);
OtpErlangObject messageReceived = mbox.receive(0);// do not wait, return null if anything received
if (messageReceived != null && messageReceived instanceof OtpErlangTuple && ((OtpErlangTuple)messageReceived).arity() == 2)
{
OtpErlangTuple cmd = ((OtpErlangTuple)messageReceived);
if (cmd.elementAt(0).equals(ref) && cmd.elementAt(1).equals(msgStop))
throw new AskedToTerminateException();
}
} catch (OtpErlangExit e) {
Helper.throwUnchecked("node exited", e);
} catch (OtpErlangDecodeException e) {
Helper.throwUnchecked("decode exception", e);
}
// resume learning.
return super.ChooseStatePairs(graph);
}
@Override
public Pair<Integer, String> CheckWithEndUser(
LearnerGraph model,
List<Label> question,
int expectedForNoRestart,
List<Boolean> consistentFacts,
PairScore pairBeingMerged,
Object[] moreOptions) {
return super.CheckWithEndUser(model, question, expectedForNoRestart,consistentFacts, pairBeingMerged, moreOptions);
}
};
if (learnerInitConfiguration.config.getAskQuestions()) // only generate initial traces if we are permited to ask questions.
learner.init(learner.GenerateInitialTraces(learnerInitConfiguration.config.getErlangInitialTraceLength()),0,0);
System.out.println("random trace generation complete");
LearnerGraph graphLearnt = learner.learnMachine(),
graphWithTrimmedLabels = new LearnerGraph(learnerInitConfiguration.config);
if (learnerInitConfiguration.config.getErlangStripModuleNamesFromFunctionsInNonGenModules())
convertLabelsToStrings(graphLearnt,graphWithTrimmedLabels);
else