Package statechum.analysis.learning.rpnicore

Examples of statechum.analysis.learning.rpnicore.LearnerGraph


   
    @Override
    public ThreadResult call() throws Exception
    {
      final int alphabet = states;
      LearnerGraph referenceGraph = null;
      ThreadResult outcome = new ThreadResult();
      WekaDataCollector dataCollector = createDataCollector(ifDepth);
      Label uniqueFromInitial = null;
      Timer timerToDetectLongRunningAutomata = new Timer("timer_to_detect_lengthy_tasks");
      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 = uniqueFromState(referenceGraph);
          if(!uniques.isEmpty())
          {
            Entry<Label,CmpVertex> entry = uniques.entrySet().iterator().next();
            referenceGraph.setInit(entry.getValue());uniqueFromInitial = entry.getKey();
          }
        }
      }
      while(pickUniqueFromInitial && uniqueFromInitial == null);
     
      LearnerEvaluationConfiguration learnerEval = new LearnerEvaluationConfiguration(config);learnerEval.setLabelConverter(converter);
      final Collection<List<Label>> testSet = null;//PaperUAS.computeEvaluationSet(referenceGraph,states*3,states*alphabet);
     
      for(int attempt=0;attempt<2;++attempt)
      {// try learning the same machine a few times
        LearnerGraph pta = new LearnerGraph(config);
        RandomPathGenerator generator = new RandomPathGenerator(referenceGraph,new Random(attempt),5,null);
        // test sequences will be distributed around
        final int pathLength = generator.getPathLength();
        // 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 = makeEven(states*traceQuantity);
        final Random rnd = new Random(seed*31+attempt);
        generator.generateRandomPosNeg(tracesToGenerate, 1, false, new RandomLengthGenerator() {
                   
            @Override
            public int getLength() {
              return (rnd.nextInt(pathLength)+1)*lengthMultiplier;
            }
   
            @Override
            public int getPrefixLength(int len) {
              return len;
            }
          });
        /*
        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.
         
        //pta.paths.augmentPTA(referenceGraph.wmethod.computeNewTestSet(referenceGraph.getInit(),1));
       
        pta.clearColours();
        synchronized (AbstractLearnerGraph.syncObj) {
          //PaperUAS.computePTASize(selectionID+" attempt: "+attempt+" with unique: ", pta, referenceGraph);
        }
       
        if (!onlyUsePositives)
        {
          assert pta.getStateNumber() > pta.getAcceptStateNumber() : "graph with only accept states but onlyUsePositives is not set";
          /*
          Map<Label,Set<Label>> infeasiblePairs = 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)]);
            }
            subsetOfPairs.put(entry.getKey(),value);
          }
          addIfThenForPairwiseConstraints(learnerEval,subsetOfPairs);
          LearnerGraph [] ifthenAutomata = Transform.buildIfThenAutomata(learnerEval.ifthenSequences, null, referenceGraph, learnerEval.config, learnerEval.getLabelConverter()).toArray(new LearnerGraph[0]);
          learnerEval.config.setUseConstraints(false);// do not use if-then during learning (refer to the explanation above)
          int statesToAdd = 1;// we are adding pairwise constraints hence only one has to be added.
          Transform.augmentFromIfThenAutomaton(pta, null, ifthenAutomata, statesToAdd);// we only need  to augment our PTA once (refer to the explanation above).
          */
        }
        else assert pta.getStateNumber() == pta.getAcceptStateNumber() : "graph with negatives but onlyUsePositives is set";
       
        LearnerThatCanClassifyPairs learnerOfPairs = null;
        LearnerGraph actualAutomaton = null;
       
        if (pickUniqueFromInitial)
        {
          pta = mergeStatesForUnique(pta,uniqueFromInitial);
          learnerOfPairs = createLearner(learnerEval,referenceGraph,dataCollector,pta);
          learnerOfPairs.setLabelsLeadingFromStatesToBeMerged(Arrays.asList(new Label[]{uniqueFromInitial}));
         
          synchronized (AbstractLearnerGraph.syncObj) {
            //PaperUAS.computePTASize(selectionID+" attempt: "+attempt+" with unique: ", pta, referenceGraph);
          }

          actualAutomaton = learnerOfPairs.learnMachine(new LinkedList<List<Label>>(),new LinkedList<List<Label>>());

          LinkedList<AMEquivalenceClass<CmpVertex,LearnerGraphCachedData>> verticesToMerge = new LinkedList<AMEquivalenceClass<CmpVertex,LearnerGraphCachedData>>();
          List<StatePair> pairsList = LearnerThatCanClassifyPairs.buildVerticesToMerge(actualAutomaton,learnerOfPairs.getLabelsLeadingToStatesToBeMerged(),learnerOfPairs.getLabelsLeadingFromStatesToBeMerged());
          if (!pairsList.isEmpty())
          {
            int score = actualAutomaton.pairscores.computePairCompatibilityScore_general(null, pairsList, verticesToMerge);
            if (score < 0)
            {
              learnerOfPairs = createLearner(learnerEval,referenceGraph,dataCollector,pta);
              learnerOfPairs.setLabelsLeadingFromStatesToBeMerged(Arrays.asList(new Label[]{uniqueFromInitial}));
              actualAutomaton = learnerOfPairs.learnMachine(new LinkedList<List<Label>>(),new LinkedList<List<Label>>());
              score = actualAutomaton.pairscores.computePairCompatibilityScore_general(null, pairsList, verticesToMerge);
              throw new RuntimeException("last merge in the learning process was not possible");
            }
            actualAutomaton = MergeStates.mergeCollectionOfVertices(actualAutomaton, null, verticesToMerge);
          }
        }
        else
        {// not merging based on a unique transition from an initial state
          learnerOfPairs = createLearner(learnerEval,referenceGraph,dataCollector,pta);
          synchronized (AbstractLearnerGraph.syncObj) {
            //PaperUAS.computePTASize(selectionID+" attempt: "+attempt+" no unique: ", pta, referenceGraph);
          }
         
          final int attemptAsFinal = attempt;
         
          TimerTask recordPta = new TimerTask() {
           
            @Override
            public void run() {
              synchronized (AbstractLearnerGraph.syncObj) {
                System.out.println("\nWARNING: "+new Date().toString()+" learner took an excessive amount of time to complete "+selectionID+"attempt="+attemptAsFinal+"; no unique");
              }
            }
          };
          timerToDetectLongRunningAutomata.schedule(recordPta,1000l*60l*20l);
          actualAutomaton = learnerOfPairs.learnMachine(new LinkedList<List<Label>>(),new LinkedList<List<Label>>());
          recordPta.cancel();
        }
       
        VertID rejectVertexID = null;
        for(CmpVertex v:actualAutomaton.transitionMatrix.keySet())
          if (!v.isAccept())
          {
            assert rejectVertexID == null : "multiple reject vertices in learnt automaton, such as "+rejectVertexID+" and "+v;
            rejectVertexID = v;break;
          }
        if (rejectVertexID == null)
          rejectVertexID = actualAutomaton.nextID(false);
        SampleData dataSample = new SampleData(null,null);
        if (learnUsingReferenceLearner)
        {
          dataSample.actualLearner=estimateDifference(referenceGraph,actualAutomaton,testSet);
          LearnerGraph outcomeOfReferenceLearner = new ReferenceLearner(learnerEval,referenceGraph,pta,false).learnMachine(new LinkedList<List<Label>>(),new LinkedList<List<Label>>());
          dataSample.referenceLearner = estimateDifference(referenceGraph, outcomeOfReferenceLearner,testSet);
          System.out.println("actual: "+actualAutomaton.getStateNumber()+" from reference learner: "+outcomeOfReferenceLearner.getStateNumber()+ " difference actual is "+dataSample.actualLearner+ " difference ref is "+dataSample.referenceLearner);
          //actualAutomaton.storage.writeGraphML("seed="+seed+";attempt="+attempt+"-actual.xml");
          //referenceGraph.storage.writeGraphML("seed="+seed+";attempt="+attempt+"-reference.xml");
          /*
          {
            GD<CmpVertex,CmpVertex,LearnerGraphCachedData,LearnerGraphCachedData> gd = new GD<CmpVertex,CmpVertex,LearnerGraphCachedData,LearnerGraphCachedData>();
View Full Code Here


  {
    super(parent, evalCnf.config);
    ifthenAutomataAsText = evalCnf.ifthenSequences;
    if(ifthenAutomataAsText == null)
      ifthenAutomataAsText = new HashSet<String>();
    tentativeAutomaton = new LearnerGraph(evalCnf.config);
  }
View Full Code Here

 
  /** Given a graph, merges a pair of states from it and returns the result. */
  @Override
  public LearnerGraph MergeAndDeterminize(LearnerGraph original, StatePair pair)
  {
    LearnerGraph result = MergeStates.mergeAndDeterminize_general(original, pair);
    return result;
  }
View Full Code Here

 
  @Override
  public LearnerGraph learnMachine()
  {
    final Configuration shallowCopy = tentativeAutomaton.config.copy();shallowCopy.setLearnerCloneGraph(false);
    LearnerGraph ptaHardFacts = new LearnerGraph(shallowCopy);// this is now cloned to eliminate counter-examples added to ptaSoftFacts by Spin
    LearnerGraph.copyGraphs(tentativeAutomaton, ptaHardFacts);
    LearnerGraph ptaSoftFacts = tentativeAutomaton;
    setChanged();tentativeAutomaton.setName(learntGraphName+"_init");
   
    if (config.isUseConstraints())
    {
      LearnerGraph updatedTentativeAutomaton = new LearnerGraph(shallowCopy);
      StringBuffer counterExampleHolder = new StringBuffer();
      if (ifthenAutomata == null) ifthenAutomata = Transform.buildIfThenAutomata(ifthenAutomataAsText, ptaHardFacts, config).toArray(new LearnerGraph[0]);

      if (!topLevelListener.AddConstraints(tentativeAutomaton,updatedTentativeAutomaton,counterExampleHolder))
        throw new IllegalArgumentException(getHardFactsContradictionErrorMessage(ifthenAutomataAsText, counterExampleHolder.toString()));
      tentativeAutomaton = updatedTentativeAutomaton;
    }
    if (tentativeAutomaton.config.getUseLTL() && tentativeAutomaton.config.getUseSpin() && !ifthenAutomataAsText.isEmpty()){
      SpinResult sr = SpinUtil.check(ptaHardFacts, ifthenAutomataAsText);
      if(!sr.isPass())
        throw new IllegalArgumentException(getHardFactsContradictionErrorMessage(ifthenAutomataAsText, sr.getCounters()));
    }

    Stack<PairScore> possibleMerges = topLevelListener.ChooseStatePairs(tentativeAutomaton);
    int iterations = 0, currentNonAmber = ptaHardFacts.getStateNumber()-ptaHardFacts.getAmberStateNumber();
    JUConstants colourToAugmentWith = tentativeAutomaton.config.getUseAmber()? JUConstants.AMBER:null;
    updateGraph(tentativeAutomaton);
    while (!possibleMerges.isEmpty())
    {
      iterations++;
      PairScore pair = possibleMerges.pop();
      LearnerGraph temp = topLevelListener.MergeAndDeterminize(tentativeAutomaton, pair);
      Collection<List<String>> questions = new LinkedList<List<String>>();
      int score = pair.getScore();
      RestartLearningEnum restartLearning = RestartLearningEnum.restartNONE;// whether we need to rebuild a PTA
                      // and restart learning.

      //updateGraph(temp.paths.getGraph(learntGraphName+"_"+counterRestarted+"_"+iterations));
      if (tentativeAutomaton.config.getUseLTL() && tentativeAutomaton.config.getUseSpin() && !ifthenAutomataAsText.isEmpty()){

        Collection<List<String>> counterExamples = SpinUtil.check(temp, tentativeAutomaton, ifthenAutomataAsText).getCounters();
        Iterator<List<String>> counterExampleIt = counterExamples.iterator();
        while(counterExampleIt.hasNext())
        {
          List<String> counterExample = counterExampleIt.next();
          topLevelListener.AugmentPTA(ptaSoftFacts, RestartLearningEnum.restartSOFT, counterExample, false,colourToAugmentWith);
          System.out.println("<temp> "+counterExample);
         
        }
        if(counterExamples.size()>0)
          restartLearning = RestartLearningEnum.restartSOFT;
      }
     
      if (config.isUseConstraints())
      {
        LearnerGraph updatedTentativeAutomaton = new LearnerGraph(shallowCopy);
        StringBuffer counterExampleHolder = new StringBuffer();
        if (!topLevelListener.AddConstraints(temp,updatedTentativeAutomaton,counterExampleHolder))
        {
          tentativeAutomaton.addToCompatibility(pair.firstElem, pair.secondElem, PAIRCOMPATIBILITY.INCOMPATIBLE);
          restartLearning = RestartLearningEnum.restartRECOMPUTEPAIRS;
          System.out.println("<info> pair "+pair+" contradicts constraints, hence recorded as incompatible");
        }
        // since we still need the outcome of merging to ask questions,
        // we delay actually performing augmentation until the time we are
        // finished with questions.
      }

      Iterator<List<String>> questionIt = null;
     
      if (restartLearning == RestartLearningEnum.restartNONE && shouldAskQuestions(score))
      {
        temp.setName(learntGraphName+"_"+iterations);
        //LearnerGraph updatedGraphActual = ComputeQuestions.constructGraphWithQuestions(pair, tentativeAutomaton, temp);
        //updatedGraphActual.setName("questions "+iterations);setChanged();updateGraph(updatedGraphActual);

        questions = topLevelListener.ComputeQuestions(pair, tentativeAutomaton, temp);// all answers are considered "hard", hence we have to ask questions based on hard facts in order to avoid prefixes which are not valid in hard facts
        questionIt = questions.iterator();
        if (questionIt.hasNext())
        {
          pair.firstElem.setHighlight(true);pair.secondElem.setHighlight(true);
          updateGraph(tentativeAutomaton);pair.firstElem.setHighlight(false);pair.secondElem.setHighlight(false);
        }
      }
     
      while (restartLearning == RestartLearningEnum.restartNONE && questionIt != null && questionIt.hasNext())
      {
        List<String> question = questionIt.next();
       
        boolean accepted = pair.getQ().isAccept();
        Pair<Integer,String> answer = null;
        if (tentativeAutomaton.config.getUseLTL() && tentativeAutomaton.config.getUseSpin() && !ifthenAutomataAsText.isEmpty())
          answer = new Pair<Integer,String>(checkWithSPIN(question),null);
       
        CmpVertex tempVertex = temp.getVertex(question);
        boolean answerFromSpin = false;
        if(answer != null && answer.firstElem >= 0)
          answerFromSpin = true;
        else
        {
          if (Boolean.valueOf(GlobalConfiguration.getConfiguration().getProperty(GlobalConfiguration.G_PROPERTIES.ASSERT)))
            if (ptaHardFacts.paths.tracePathPrefixClosed(question) == AbstractOracle.USER_ACCEPTED)
              throw new IllegalArgumentException("question "+ question+ " has already been answered");
          List<Boolean> acceptedElements = null;
          acceptedElements = PathRoutines.mapPathToConfirmedElements(ptaHardFacts,question,ifthenAutomata);
         
          answer = topLevelListener.CheckWithEndUser(tentativeAutomaton, question,
              tempVertex.isAccept()?AbstractOracle.USER_ACCEPTED:question.size() - 1,
                  acceptedElements,
              new Object[] { "LTL","IFTHEN","IGNORE QUESTION","MARK AS INCOMPATIBLE"});
        }
        if (answer.firstElem == AbstractOracle.USER_CANCELLED)
        {
          System.err.println("CANCELLED");
          return null;
        }
        else
        if (answer.firstElem == AbstractOracle.USER_IGNORED)
        {// do nothing
          restartLearning = RestartLearningEnum.restartNONE;
          System.err.println("<ignore> "+question);
        }
        else
        if (answer.firstElem == AbstractOracle.USER_INCOMPATIBLE)
        {
          tentativeAutomaton.addToCompatibility(pair.firstElem, pair.secondElem, PAIRCOMPATIBILITY.INCOMPATIBLE);
          restartLearning = RestartLearningEnum.restartRECOMPUTEPAIRS;
        }
        else
        if (answer.firstElem == AbstractOracle.USER_ACCEPTED)
        {
          if(!answerFromSpin) // only add to hard facts when obtained directly from a user or from autofile
            AugumentPTA_and_QuestionPTA(ptaHardFacts,RestartLearningEnum.restartHARD,question, true,colourToAugmentWith);
         
          if (tentativeAutomaton.config.getUseLTL() && tentativeAutomaton.config.getUseSpin()) topLevelListener.AugmentPTA(ptaSoftFacts,RestartLearningEnum.restartSOFT,question, true,colourToAugmentWith);

          if (!tempVertex.isAccept())
          {// contradiction with the result of merging
            if(!answerFromSpin)
              restartLearning = RestartLearningEnum.restartHARD;
            else
              restartLearning = RestartLearningEnum.restartSOFT;
           
          }
        } else
        if (answer.firstElem >= 0)
        {// The sequence has been rejected by a user
          assert answer.firstElem < question.size();
          LinkedList<String> subAnswer = new LinkedList<String>();
          subAnswer.addAll(question.subList(0, answer.firstElem + 1));
          if(!answerFromSpin) // only add to hard facts when obtained directly from a user or from autofile
            AugumentPTA_and_QuestionPTA(ptaHardFacts, RestartLearningEnum.restartHARD,subAnswer, false,colourToAugmentWith);

          if (tentativeAutomaton.config.getUseLTL() && tentativeAutomaton.config.getUseSpin()) topLevelListener.AugmentPTA(ptaSoftFacts,RestartLearningEnum.restartSOFT,subAnswer, false,colourToAugmentWith);
          // important: since vertex IDs is
          // only unique for each instance of ComputeStateScores, only
          // one instance should ever receive calls to augmentPTA

          if ((answer.firstElem < question.size() - 1) || tempVertex.isAccept())
          {// contradiction with the result of merging
            assert accepted == true;
            if(!answerFromSpin)
              restartLearning = RestartLearningEnum.restartHARD;
            else
              restartLearning = RestartLearningEnum.restartSOFT;
           
          }
        }
        else
          if(answer.firstElem == AbstractOracle.USER_LTL || answer.firstElem == AbstractOracle.USER_IFTHEN)
          {
            String answerType = null;
            if (answer.firstElem == AbstractOracle.USER_LTL)
              answerType = QSMTool.cmdLTL;
            else
              if (answer.firstElem == AbstractOracle.USER_IFTHEN)
                answerType = QSMTool.cmdIFTHENAUTOMATON;
              else
                throw new IllegalArgumentException("unexpected user choice kind "+answer.firstElem);

            restartLearning = RestartLearningEnum.restartRECOMPUTEQUESTIONS;
            String addedConstraint = answer.secondElem;
            boolean obtainedLTLViaAuto = addedConstraint != null;
            if (addedConstraint == null) addedConstraint = JOptionPane.showInputDialog("New "+answerType+" formula:");
            if(addedConstraint != null && addedConstraint.length() != 0)
            {
              if (!obtainedLTLViaAuto) System.out.println(QUESTION_USER+" "+question.toString()+ " <"+answerType+"> "+addedConstraint);
              Set<String> tmpLtl = new HashSet<String>();tmpLtl.addAll(ifthenAutomataAsText);tmpLtl.add(answerType+" "+addedConstraint);
              if(!config.isUseConstraints()){
                Collection<List<String>> counters = SpinUtil.check(ptaHardFacts, tmpLtl).getCounters();
                if (counters.size()>0)
                {
                  String errorMessage = getHardFactsContradictionErrorMessage(tmpLtl, counters);
                  if (obtainedLTLViaAuto) // cannot recover from autosetting, otherwise warn a user
                    throw new IllegalArgumentException(errorMessage);
                 
                  // if not obtained via auto, complain
                  System.out.println(errorMessage);
                }
              }
              else{
                LearnerGraph tmpIfthenAutomata[] = Transform.buildIfThenAutomata(tmpLtl, tentativeAutomaton, config).toArray(new LearnerGraph[0]);
                LearnerGraph updatedTentativeAutomaton = new LearnerGraph(shallowCopy);

                LearnerGraph.copyGraphs(tentativeAutomaton, updatedTentativeAutomaton);
                try {
                  Transform.augmentFromIfThenAutomaton(updatedTentativeAutomaton, null, tmpIfthenAutomata, config.getHowManyStatesToAddFromIFTHEN());
                } catch (AugmentFromIfThenAutomatonException e) {
                // merge failed because the constraints disallowed it, hence return a failure
                  StringBuffer counterExampleHolder = new StringBuffer();
                  e.getFailureLocation(counterExampleHolder);
                  String errorMessage = getHardFactsContradictionErrorMessage(ifthenAutomataAsText, counterExampleHolder.toString());
                  if (obtainedLTLViaAuto) // cannot recover from autosetting, otherwise warn a user
                    throw new IllegalArgumentException(errorMessage);
                      // if not obtained via auto, complain
                          System.out.println(errorMessage);
                }
              }
              // the current set of constraints does not contradict hard facts, update them and restart learning.
              ifthenAutomataAsText.add(answerType+" "+addedConstraint);
             
              // make sure constraints are rebuilt if in use
              if (config.isUseConstraints())
                ifthenAutomata = Transform.buildIfThenAutomata(ifthenAutomataAsText, ptaHardFacts, config).toArray(new LearnerGraph[0]);
             
              restartLearning = RestartLearningEnum.restartHARD;
            }
            // no formula was entered, do not set the <em>questionAnswered</em> to answered, hence
              // when we get to the top of the loop, we'll re-pop the previous question.
          }
          else
            throw new IllegalArgumentException("unexpected user choice "+answer);
       
        if ( (config.isUseConstraints() && restartLearning == RestartLearningEnum.restartNONE) || restartLearning == RestartLearningEnum.restartRECOMPUTEQUESTIONS)
        {
          questions = topLevelListener.RecomputeQuestions(pair, tentativeAutomaton, temp);// all answers are considered "hard", hence we have to ask questions based on hard facts in order to avoid prefixes which are not valid in hard facts
          questionIt = questions.iterator();restartLearning = RestartLearningEnum.restartNONE;
        }
      } // loop of questions

      if (restartLearning == RestartLearningEnum.restartHARD ||
          restartLearning == RestartLearningEnum.restartSOFT)
      {// restart learning
       
        if (restartLearning == RestartLearningEnum.restartHARD)
        {
          if (config.isSpeculativeQuestionAsking())
            if (speculativeGraphUpdate(possibleMerges, ptaHardFacts))
              return null;// this is the case when a user cancels the learning process when presented by "speculative" questions.
          LearnerGraph.copyGraphs(ptaHardFacts,ptaSoftFacts);// this is cloned to eliminate counter-examples added to ptaSoftFacts by Spin
        }
        tentativeAutomaton = ptaSoftFacts;// no need to clone - this is the job of mergeAndDeterminize anyway
        tentativeAutomaton.clearColoursButAmber();// this one will clear all colours if amber mode is not set.

        setChanged();
      }
      else
      if (restartLearning == RestartLearningEnum.restartNONE)
      {
        // At this point, tentativeAutomaton may have been modified because
        // it may point to
        // the original PTA which will be modified as a result of new
        // sequences being added to it.
        // temp is different too, hence there is no way for me to
        // compute compatibility score here.
        // This is hence computed inside the obtainPair method.

        // keep going with the existing model
        tentativeAutomaton = temp;
      }
      // if restartLearning == RestartLearningEnum.restartRECOMPUTEPAIRS, we do nothing, i.e. attempt to get state pairs again.

      if (restartLearning != RestartLearningEnum.restartRECOMPUTEPAIRS && config.isUseConstraints())
      {// Augmentation from IF-THEN does not use incompatibility constraints in a tentative automaton hence no point in re-augmenting (especially given that I do not have an automaton from before augmentation preserved).
        LearnerGraph updatedTentativeAutomaton = new LearnerGraph(shallowCopy);
        StringBuffer counterExampleHolder = new StringBuffer();
        if (!topLevelListener.AddConstraints(tentativeAutomaton,updatedTentativeAutomaton,counterExampleHolder))
          throw new IllegalArgumentException(getHardFactsContradictionErrorMessage(ifthenAutomataAsText, counterExampleHolder.toString()));
        tentativeAutomaton = updatedTentativeAutomaton;
      }
View Full Code Here

      PairScore pair = possibleMerges.pop();
      int score = pair.getScore();

      if(shouldAskQuestions(score))
      {
        LearnerGraph tempNew = null;
        try
        {
          tempNew = topLevelListener.MergeAndDeterminize(ptaHardFacts, pair);
        }
        catch(IllegalArgumentException ex)
        {// ignore - tempNew is null anyway         
        }
       
        if (tempNew != null) // merge successful - it would fail if our updates to newPTA have modified tentativeAutomaton (the two are often the same graph)
        {         
          for(List<String> question:topLevelListener.ComputeQuestions(pair, ptaHardFacts, tempNew))
          {
            List<Boolean> acceptedElements = null;
            if (tentativeAutomaton.config.isUseConstraints())
              acceptedElements = PathRoutines.mapPathToConfirmedElements(ptaHardFacts,question,ifthenAutomata);
            Pair<Integer,String> answer = topLevelListener.CheckWithEndUser(tentativeAutomaton,question, tempNew.getVertex(question).isAccept()?AbstractOracle.USER_ACCEPTED:question.size() - 1,acceptedElements,new Object [] {"Test"});
            if (answer.firstElem == AbstractOracle.USER_CANCELLED)
            {
              System.out.println("CANCELLED");
              return true;
            }
View Full Code Here

  /** Each test starts with this configuration. */
  private Configuration mainConfiguration = null;
 
  protected void checkLearner(String fsmString, String name,String [][] plus, String [][] minus)
  {
    final LearnerGraph expected = FsmParser.buildLearnerGraph(fsmString, name,testConfig,getLabelConverter());
   
    // now sanity checking on the plus and minus sets
    for(String [] path:plus)
      assert AbstractOracle.USER_ACCEPTED == expected.paths.tracePathPrefixClosed(AbstractLearnerGraph.buildList(Arrays.asList(path),config,getLabelConverter()));
    for(String [] path:minus)
      assert AbstractOracle.USER_ACCEPTED != expected.paths.tracePathPrefixClosed(AbstractLearnerGraph.buildList(Arrays.asList(path),config,getLabelConverter()));
    // Visualiser.getVisualiser()
    Learner l = new RPNIUniversalLearner(null,new LearnerEvaluationConfiguration(null,null,testConfig,null,null))
    {
      @Override
      public LearnerGraph MergeAndDeterminize(LearnerGraph original, StatePair pair)
      {
        // Check that compatibility score computation gives the same response as if we did merge and computed a difference between the number of states.
        ScoreMode origScore = original.config.getLearnerScoreMode();original.config.setLearnerScoreMode(ScoreMode.COMPATIBILITY);
        long compatibilityScore = original.pairscores.computePairCompatibilityScore(pair);
        original.config.setLearnerScoreMode(origScore);
        LearnerGraph outcome = super.MergeAndDeterminize(original, pair);
        Assert.assertEquals(compatibilityScore+1,original.getStateNumber()-outcome.getStateNumber());
        return outcome;
      }

      @Override
      public Pair<Integer,String> CheckWithEndUser(
          @SuppressWarnings("unused"LearnerGraph model,
          List<Label> question, @SuppressWarnings("unused") int valueForNoRestart,
          @SuppressWarnings("unused") List<Boolean> acceptedElements,
          @SuppressWarnings("unused") PairScore pairBeingMerged,
          @SuppressWarnings("unused"final Object [] moreOptions)
      {
        Pair<Integer,String> oracleAnswer = new Pair<Integer,String>(expected.paths.tracePathPrefixClosed(question),null);
        return oracleAnswer;       
      }
     
    };
    config.setDebugMode(false);
    //l.setPairsMergedPerHypothesis(0);
    //l.setGeneralisationThreshold(1);
    //l.setCertaintyThreshold(5);
    testConfig.setLearnerIdMode(IDMode.POSITIVE_NEGATIVE);
    LearnerGraph learntStructureA = new LearnerGraph(l.learnMachine(buildSet(plus,testConfig,getLabelConverter()), buildSet(minus,testConfig,getLabelConverter())),expected.config);
    // Now do the same with ptasets instead of real sets
    PTASequenceSet plusPTA = new PTASequenceSet();plusPTA.addAll(buildSet(plus,testConfig,getLabelConverter()));PTASequenceSet minusPTA = new PTASequenceSet();minusPTA.addAll(buildSet(minus,testConfig,getLabelConverter()));
    LearnerGraph learntStructureB = new LearnerGraph(l.learnMachine(plusPTA, minusPTA),expected.config);
    Assert.assertNull(WMethod.checkM(learntStructureA, learntStructureB));
    LearnerGraph learntMachineNoRejects = new LearnerGraph(expected.config);
    AbstractPathRoutines.removeRejectStates(learntStructureA,learntMachineNoRejects);
    Assert.assertNull(WMethod.checkM(learntMachineNoRejects, expected));
  }
View Full Code Here

  DeterministicVertex p = new DeterministicVertex("P"), q= new DeterministicVertex("Q");
  /** Checks that both the old and the new algorithm reports a pair of states as incompatible. */
  public final void testNewLearnerIncompatible(String fsm, String name)
  {
    LearnerGraph s = FsmParser.buildLearnerGraph(fsm, name,testConfig,getLabelConverter());
    DirectedSparseGraph g = s.pathroutines.getGraph();
    OrigStatePair pairOrig = new OrigStatePair(DeterministicDirectedSparseGraph.findVertex(JUConstants.LABEL, VertexID.parseID("B"), g),
        DeterministicDirectedSparseGraph.findVertex(JUConstants.LABEL, VertexID.parseID("A"), g));
    StatePair pairNew = new StatePair(s.findVertex(VertexID.parseID("B")),s.findVertex(VertexID.parseID("A")));
    doneEdges = new HashSet<DirectedSparseEdge>();
    long origScore = computeScore(g, pairOrig),
      newScoreA = s.pairscores.computeStateScore(pairNew);
    Assert.assertEquals(-1, origScore);
    Assert.assertEquals(-1, newScoreA);
View Full Code Here

  /** Checks that both the old and the two new algorithms report the same score for a pair of states and ask the same questions.
   * @param states being merged are called "A" and "B".
   */
  public final void testNewLearnerQuestions(String fsm, int expectedScore, String learnerName)
  {
    LearnerGraph s = FsmParser.buildLearnerGraph(fsm, learnerName,testConfig,getLabelConverter());
    DirectedSparseGraph g = s.pathroutines.getGraph();
    OrigStatePair pairOrig =
      new OrigStatePair(
          DeterministicDirectedSparseGraph.findVertex(JUConstants.LABEL, VertexID.parseID("B"), g),
          DeterministicDirectedSparseGraph.findVertex(JUConstants.LABEL, VertexID.parseID("A"), g));
    StatePair pairNew1 = new StatePair(s.findVertex(VertexID.parseID("B")),s.findVertex(VertexID.parseID("A")));
    DirectedSparseGraph
      temp = mergeAndDeterminize((Graph)g.copy(), pairOrig),
      tempB = MergeStates.mergeAndDeterminize(g, pairNew1,testConfig);
   
    // Now check that ComputeStateScores properly does  mergeAndDeterminize
    // (on the test data we are dealing with in these tests, there are separate tests for mergeAndDeterminize)
    LearnerGraph tempG = new LearnerGraph(temp,testConfig), tempBG = new LearnerGraph(tempB,testConfig);
    Assert.assertEquals(false, tempG.pathroutines.checkUnreachableStates());Assert.assertEquals(false, tempBG.pathroutines.checkUnreachableStates());
    Assert.assertNull(WMethod.checkM(tempG, tempBG));
   
   
    doneEdges = new HashSet<DirectedSparseEdge>();
    long origScore = computeScore(g, pairOrig),
      newScoreA = s.pairscores.computeStateScore(pairNew1),
      newScoreB = s.pairscores.computePairCompatibilityScore(pairNew1),
      newScoreC = s.pairscores.computePairCompatibilityScore_general(pairNew1,null, new LinkedList<AMEquivalenceClass<CmpVertex,LearnerGraphCachedData>>());

    LearnerGraph learner2 = new LearnerGraph(g, testConfig);
    StatePair pairNew2 = new StatePair(learner2.findVertex(VertexID.parseID("B")),learner2.findVertex(VertexID.parseID("A")));
    //Visualiser.updateFrame(g, MergeStates.mergeAndDeterminize_general(learner2, pairNew2).pathroutines.getGraph(learnerName));Visualiser.waitForKey();
    Collection<List<Label>>
      // Since computeQS assumes that red names remain unchanged in the merged version, I have to use a specific merging procedure
      questionsB = ComputeQuestions.computeQS_orig(pairNew2, learner2,MergeStates.mergeAndDeterminize(learner2, pairNew2)),
      questionsC = ComputeQuestions.computeQS_orig(pairNew2, learner2,MergeStates.mergeAndDeterminize_general(learner2, pairNew2)),
View Full Code Here

  public static final String PTA1 = "\nA-p->I-q->B"+"\nB-a->B1-a-#B2\nB1-b->B3-b->B4\n";
 
  @Test(expected = IllegalArgumentException.class)
  public final void testLearnerFailsWhenRedNotFound()
  {
    ComputeQuestions.computeQS_orig(new StatePair(null,new DeterministicVertex("non-existing")), new LearnerGraph(testConfig), new LearnerGraph(testConfig));
  }
View Full Code Here

    Assert.assertNotNull("state "+stateRed+" was not found", a);
    Assert.assertNotNull("state "+stateBlue+" was not found", b);
   
    OrigStatePair pairOrig = new OrigStatePair(b,a);
    StatePair pairNew1 = new StatePair(DeterministicDirectedSparseGraph.findVertexNamed(VertexID.parseID(stateBlue), g),DeterministicDirectedSparseGraph.findVertexNamed(VertexID.parseID(stateRed), g));
    LearnerGraph l = new LearnerGraph(g, testConfig);
    StatePair pairNew2 = new StatePair(l.findVertex(VertexID.parseID(stateBlue)),l.findVertex(VertexID.parseID(stateRed)));
    LearnerGraph
      mergeResultA = new LearnerGraph(Test_Orig_RPNIBlueFringeLearner.mergeAndDeterminize(g, pairOrig),testConfig),
      mergeResultB = new LearnerGraph(MergeStates.mergeAndDeterminize(g2, pairNew1,testConfig),testConfig),
      mergeResultC = new LearnerGraph(MergeStates.mergeAndDeterminize(l, pairNew2).pathroutines.getGraph(),testConfig),
      mergeResultD = new LearnerGraph(MergeStates.mergeAndDeterminize_general(l, pairNew2).pathroutines.getGraph(),testConfig),
      expectedMachine = buildLearnerGraph(expectedFSM, "expected machine",testConfig,getLabelConverter());

    TestEquivalenceChecking.checkM(machineToMerge, new LearnerGraph(g2,testConfig), testConfig, getLabelConverter());
   
    Assert.assertFalse("unreachable states - original",mergeResultA.pathroutines.checkUnreachableStates());
    Assert.assertFalse("unreachable states",mergeResultB.pathroutines.checkUnreachableStates());
    Assert.assertFalse("unreachable states",mergeResultC.pathroutines.checkUnreachableStates());
    Assert.assertFalse("unreachable states",mergeResultD.pathroutines.checkUnreachableStates());
View Full Code Here

TOP

Related Classes of statechum.analysis.learning.rpnicore.LearnerGraph

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.