Package statechum.analysis.learning

Examples of statechum.analysis.learning.StatePair


    Queue<Boolean> currentRedFromPta = new LinkedList<Boolean>();// FIFO queue containing true if the red node comes from a branch of a PTA which has been previously already merged into the machine
    currentExplorationBoundary.add(origPair);currentRedFromPta.add(false);
   
    while(!currentExplorationBoundary.isEmpty())
    {
      StatePair currentPair = currentExplorationBoundary.remove();Boolean redFromPta = currentRedFromPta.remove();
      boolean RedAndBlueToBeMerged = false;// this one is set to true if states in the current pair have to be merged.
      // This will be so for all state pairs where a blue node can
      // make moves which the red one cannot match. The term "merged" does not refer to whether
      // two nodes are actually merged - they have to be anyway, however if there are sequences of
      // nodes with identical moves, PTA nodes do not contribute to anything - we only need
      // to consider those which branch. mergedVertices is only updated when we find a blue vertex which
      // can accept input a red node cannot accept.
      //System.out.println(" "+currentPair);
      if (currentPair.getQ().isAccept() != currentPair.getR().isAccept())
        return -1;// incompatible states
      if (!redFromPta.booleanValue())
        ++score;
      Map<String,CmpVertex> targetBlue = coregraph.transitionMatrix.get(currentPair.getQ());

      for(Entry<String,CmpVertex> blueEntry:targetBlue.entrySet())
      {
        CmpVertex nextRedState = coregraph.transitionMatrix.get(currentPair.getR()).get(blueEntry.getKey());
        if (nextRedState != null)
        {// both states can make a transition - this would be the case of "non-determinism" for Merge&Determinize
         
          // PTA does not have loops, but the original automaton has
          // and one of those loops is not on the transition diagram, namely the one related to B=A
          if (nextRedState == origPair.getQ())
          {
            nextRedState = origPair.getR(); // emulates the new loop
            redFromPta = coregraph.config.getLearnerScoreMode() != Configuration.ScoreMode.COMPATIBILITY; // and since the original score computation algorithm cannot do this, we pretend to be unable to do this either
            // The problem is that since we effectively merge the
            // states at this point, a loop introduced by merging
            // adjacent states may suck many PTA states into it,
            // so that two transitions which would not normally be
            // near each other will be merged. For this reason, it
            // is possible that our score computation will deliver
            // a higher value that the conventional matching
            // (where in the considered situation we'll be
            // matching PTA with itself and PTA may be sparse).
          }

          StatePair nextStatePair = new StatePair(blueEntry.getValue(),nextRedState);
          currentExplorationBoundary.offer(nextStatePair);currentRedFromPta.offer(redFromPta);
        }
        else
        {// the current red state cannot make a transition, perhaps PTA states associated with it can
          nextRedState = findNextRed(mergedVertices,currentPair.getR(),blueEntry.getKey());
          if (nextRedState != null)
          {// both states can make a transition - this would be the case of "non-determinism" for Merge&Determinize
           // The red state is the one originally from a previously-merged PTA branch, so here we are merging PTA with itself.

            // Since we are merging PTA with itself and PTA does not have loops, we cannot reenter the original blue state. Moreover,
            // since we called findNextRed, we are looking at transitions from the PTA states. For this reason, we cannot enter the
            // blue state since PTA does not have loops.
            assert nextRedState != origPair.getQ() : "inconsistent PTA";
           
            StatePair nextStatePair = new StatePair(blueEntry.getValue(),nextRedState);
            currentExplorationBoundary.offer(nextStatePair);currentRedFromPta.offer(coregraph.config.getLearnerScoreMode() != Configuration.ScoreMode.COMPATIBILITY);// from now on, no increments to the score
          }
          else
          {
            // If the blue can make a move, but the red one cannot, it means that the blue vertex has
View Full Code Here


   
    Queue<StatePair> currentExplorationBoundary = new LinkedList<StatePair>();// FIFO queue containing pairs to be explored
    currentExplorationBoundary.add(origPair);
    while(!currentExplorationBoundary.isEmpty())
    {
      StatePair currentPair = currentExplorationBoundary.remove();
      if (currentPair.firstElem.isAccept() != currentPair.secondElem.isAccept())
      {
        score = -1;
        break;// incompatibility
      }
      EquivalenceClass firstClass = stateToEquivalenceClass.get(currentPair.firstElem);
      EquivalenceClass secondClass= stateToEquivalenceClass.get(currentPair.secondElem);
      EquivalenceClass equivalenceClass = null;
      if (firstClass == null)
      {
        if (secondClass == null)
        {// a new pair has been discovered, populate from the current transition matrix.
          equivalenceClass = new EquivalenceClass(equivalenceClassNumber++);
          assert coregraph.transitionMatrix.containsKey(currentPair.firstElem) : " state "+currentPair.firstElem+" is not in the graph";
          assert coregraph.transitionMatrix.containsKey(currentPair.secondElem) : " state "+currentPair.firstElem+" is not in the graph";
          equivalenceClass.addFrom(currentPair.firstElem,coregraph.transitionMatrix.get(currentPair.firstElem).entrySet());
          equivalenceClass.mergeWith(currentPair.secondElem,coregraph.transitionMatrix.get(currentPair.secondElem).entrySet());
          stateToEquivalenceClass.put(currentPair.firstElem,equivalenceClass);
          stateToEquivalenceClass.put(currentPair.secondElem,equivalenceClass);
        }
        else
        {// first is null, second is not, record first as a member of the equivalence class the second one belongs to.
          equivalenceClass = secondClass;
          equivalenceClass.mergeWith(currentPair.firstElem,coregraph.transitionMatrix.get(currentPair.firstElem).entrySet());
          stateToEquivalenceClass.put(currentPair.firstElem,equivalenceClass);
        }
      }
      else
      {
        if (secondClass == null)
        {// second is null, first is not, record second as a member of the equivalence class the first one belongs to.
          equivalenceClass = firstClass;
          equivalenceClass.mergeWith(currentPair.secondElem,coregraph.transitionMatrix.get(currentPair.secondElem).entrySet());
          stateToEquivalenceClass.put(currentPair.secondElem,equivalenceClass);
        }
        else
          if (firstClass.ClassNumber != secondClass.ClassNumber)
          {
            // if the two are the same, we've seen this pair before - ignore this case
            // neither are null, hence it looks like we have to merge the two equivalent classes - doing this via inplace update
            // Tested by testPairCompatible_general_C()
            equivalenceClass = firstClass;
            equivalenceClass.mergeWith(secondClass);// merge equivalence classes
            // I cannot keep secondClass in the table because a number of states point to it.
            // Subsequently, I may wish to merge the first class with another one, but there is
            // nothing to suggest that the secondClass which I just merged in, has to be merged into
            // that "another one". For this reason, I keep a collection of all states in each
            // equivalence class and remap stateToEquivalenceClass when equivalence classes are merged.
           
            for(CmpVertex vert:secondClass.getStates())
              stateToEquivalenceClass.put(vert,equivalenceClass);
            if (LearnerGraph.testMode)
              for(Entry<CmpVertex,EquivalenceClass> entry:stateToEquivalenceClass.entrySet())
                assert entry.getValue().ClassNumber != secondClass.ClassNumber;
          }
      }

     
      // We reconsider every equivalence class which has changed which is the case if equivalenceClass != null.
      // Note there may be still pairs from the past which may have originally
      // belonged to the two classes which got subsequently merged. These pairs
      // will remain on the exploration stack and will be ignored below.
      if (equivalenceClass != null)
      {
        //if (coregraph.getStateNumber() == 1268) System.out.println(equivalenceClass.getNumber()+" ,"+equivalenceClass.getStates().size());
        // Now we have a single equivalence class in the form of a list of <label,next vertex> entries, explore all matching transitions,
        // which correspond to sequences where the first element is the same (we are using sorted sets).
        Iterator<StringVertexPair> firstTransitionIter = equivalenceClass.getOutgoing().iterator();

        while(firstTransitionIter.hasNext())
        {
          StringVertexPair firstTransition=firstTransitionIter.next();
          EquivalenceClass fClass = stateToEquivalenceClass.get (firstTransition.secondElem);

          Iterator<StringVertexPair> secondTransitionIter = equivalenceClass.getNewOutgoing().tailSet(firstTransition).iterator();
          while (secondTransitionIter.hasNext())
          {
            StringVertexPair secondTransition = secondTransitionIter.next();
            if (!firstTransition.firstElem.equals(secondTransition.firstElem))
              break;// go to the end of the sequence of outgoing transitions with the same label.
            EquivalenceClass sClass = stateToEquivalenceClass.get(secondTransition.secondElem);
            if (fClass == null || sClass == null || !fClass.equals(sClass))
            {// this is the case when a pair of states will have to be merged.
              StatePair nextPair = new StatePair(firstTransition.secondElem,secondTransition.secondElem);
              currentExplorationBoundary.offer(nextPair);
              ++score;// every matched pair increments the score.
            }
          }
        }
View Full Code Here

    Queue<StatePair> currentExplorationBoundary = new LinkedList<StatePair>();// FIFO queue
    currentExplorationBoundary.add(pair);currentExplorationBoundary.offer(null);
   
    while(!foundKTail)
    {
      StatePair currentPair = currentExplorationBoundary.remove();
      if (currentPair == null)
      {// we got to the end of a wave
        if (currentExplorationBoundary.isEmpty())
          break;// we are at the end of the last wave, stop looping.

        // mark the end of a wave.
        currentExplorationBoundary.offer(null);currentExplorationDepth++;
      }
      else
      {
        Map<String,CmpVertex> targetRed = coregraph.transitionMatrix.get(currentPair.getR()),
          targetBlue = coregraph.transitionMatrix.get(currentPair.getQ());
 
        for(Entry<String,CmpVertex> redEntry:targetRed.entrySet())
        {
          CmpVertex nextBlueState = targetBlue.get(redEntry.getKey());
          if (nextBlueState != null)
          {// both states can make a transition
            if (redEntry.getValue().isAccept() != nextBlueState.isAccept())
              return -1;// incompatible states
           
            if (coregraph.config.getLearnerScoreMode() == Configuration.ScoreMode.KTAILS &&
                currentExplorationDepth >= coregraph.config.getKlimit())
            {
              foundKTail = true;
              break;// we found a path of the "currentExplorationDepth" length and using the KTAILS method, hence stop the loop.
            }

            ++score;
 
            StatePair nextStatePair = new StatePair(nextBlueState,redEntry.getValue());
            currentExplorationBoundary.offer(nextStatePair);
          }
          // if the red can make a move, but the blue one cannot, ignore this case.
        }
      }
View Full Code Here

        while(stateB_It.hasNext())
        {
          Entry<CmpVertex,Map<String,List<CmpVertex>>> stateB = stateB_It.next();
          if (LearnerGraphND.ignoreRejectStates.stateToConsider(stateB.getKey()))
          {
            StatePair currentPair = new StatePair(entryA.getKey(),stateB.getKey());
            if (gr.pairscores.computePairCompatibilityScore_general(currentPair, new LinkedList<AMEquivalenceClass<CmpVertex,LearnerGraphCachedData>>()) < 0)
            {// result is constructed as a synchronized set
              result.add(currentPair);
            }
          }           
View Full Code Here

    HashSet<StatePair> incompatibles = new HashSet<StatePair>();
    StatesToConsider filter = LearnerGraphND.ignoreRejectStates;
    GDLearnerGraph ndGraph = new GDLearnerGraph(gr,filter, false);
    for(StringPair p:incompatibles_list)
    {
      incompatibles.add(new StatePair(gr.findVertex(p.firstElem),gr.findVertex(p.secondElem)));
      incompatibles.add(new StatePair(gr.findVertex(p.secondElem),gr.findVertex(p.firstElem)));
    }
    Set<StatePair> incompatiblePairs = new HashSet<StatePair>();
    for(StatePair s:buildSetOfIncompatiblePairsSlowly(gr,ThreadNumber))
    {
      incompatiblePairs.add(s);incompatiblePairs.add(new StatePair(s.secondElem,s.firstElem));
    }
    // incompatiblePairs these are the pairs which cannot be merged which may be a larger set than
    // the set of clearly incompatible pairs, because incompatiblePairs is computed based on
    // the outcome of computePairCompatibilityScore_general. The difference between computing incompatibility of pairs
    // and doing computePairCompatibilityScore_general is that when pairs are merged, more traces
    // are created, hence it is possible that some of those new traces will be in conflict.
    // Example: states A3 and A2 in findIncompatibleStates6()
    HashSet<StatePair> pairs_extra = new HashSet<StatePair>();pairs_extra.addAll(incompatibles);pairs_extra.removeAll(incompatiblePairs);
    Assert.assertTrue("compatible pairs included :"+pairs_extra,pairs_extra.isEmpty());// this is a check that incompatibles_list does not include any compatible pairs

    final int size=ndGraph.getPairNumber();
    final int highNumber = 10000;
    int pairs[]=new int[size];for(int i=0;i<pairs.length;++i) pairs[i]=highNumber;
   
    // reverseMap maps state pair number to the actual state pairs, we slowly build it here
    // rather then rely on getPairScore() which may have not even been written when
    // I was doing this kind of testing.
    reverseMap = new HashMap<Integer,StatePair>();
    for(CmpVertex A:gr.transitionMatrix.keySet())
      if (filter.stateToConsider(A))
        for(CmpVertex B:gr.transitionMatrix.keySet())
          if (filter.stateToConsider(B))
            reverseMap.put(ndGraph.vertexToIntNR(A, B), new StatePair(A,B));
    Assert.assertEquals(size,reverseMap.size());
   
    ndGraph.buildMatrix(ThreadNumber);
    ndGraph.findIncompatiblePairs(pairs,ThreadNumber);
   
    int cnt=0;
    for(int i=0;i<pairs.length;++i)
    {
      StatePair pair = reverseMap.get(i);
      if (incompatibles.contains(pair))
        Assert.assertEquals("pair ("+pair.firstElem+","+pair.secondElem+", id "+i+") should be marked as incompatible",
            PAIR_INCOMPATIBLE,pairs[i]);// this pair is not compatible
      else
        Assert.assertEquals("invalid counter for pair ("+pair.firstElem+","+pair.secondElem+")",
View Full Code Here

    LearnerGraph fsmToAdd = new LearnerGraph(TestFSMAlgo.buildGraph("A-a->B-a->Q", "testAddToGraph1"),Configuration.getDefaultConfiguration());
    CmpVertex newA = Transform.addToGraph(fsm, fsmToAdd);
    WMethod.checkM(fsm,fsmSrc,fsm.init,fsmSrc.init);
    WMethod.checkM(fsm,fsmToAdd,newA,fsmToAdd.init);
   
    StatePair whatToMerge = new StatePair(fsm.init,newA);
    LinkedList<Collection<CmpVertex>> collectionOfVerticesToMerge = new LinkedList<Collection<CmpVertex>>();
    Assert.assertTrue(0 < fsm.pairscores.computePairCompatibilityScore_general(whatToMerge,collectionOfVerticesToMerge));
    LearnerGraph result = MergeStates.mergeAndDeterminize_general(fsm, whatToMerge,collectionOfVerticesToMerge);
    WMethod.checkM(result,fsmSrc,result.init,fsmSrc.init);
  }
View Full Code Here

   
    // Here P is a singleton and R is empty, hence they are ignored.
    List<StatePair> outcome = MarkovClassifier.collectionOfSetsToPairs(collectionOfSets);
    // three pairs, here we have a hardwired expected response that unfortunately depends on the implementation of collectionOfSetsToPairs.
    Assert.assertEquals(3,outcome.size());
    Assert.assertTrue(outcome.contains(new StatePair(gr.findVertex("B"),gr.findVertex("C"))));
    Assert.assertTrue(outcome.contains(new StatePair(gr.findVertex("C"),gr.findVertex("D"))));
    Assert.assertTrue(outcome.contains(new StatePair(gr.findVertex("D"),gr.findVertex("E"))));
  }
View Full Code Here

    final Queue<StatePair> currentExplorationBoundary = new LinkedList<StatePair>();// FIFO queue
    final Map<StatePair,CmpVertex> pairsToGraphStates = new HashMap<StatePair,CmpVertex>();
    LearnerGraph result = new LearnerGraph(config);result.initEmpty();
    // Two sets are constructed so that I do not have to think about vertices which are shared between the two graphs regardless whether such a case is possible or not.
    final Set<CmpVertex> encounteredGraph = new HashSet<CmpVertex>();
    StatePair statePair = new StatePair(graph.getInit(),from.getInit());
    encounteredGraph.add(statePair.firstElem);
    result.setInit(AbstractLearnerGraph.cloneCmpVertex(graph.getInit(), config));
    result.transitionMatrix.put(result.getInit(), result.createNewRow());
    pairsToGraphStates.put(statePair, result.getInit());
    boolean graphModified = false;
    if (statePair.firstElem.isAccept() && !statePair.secondElem.isAccept())
    {// initial states are incompatible because the tentative automaton is accept and
     // the max automaton is reject, hence either override if possible and requested or throw.
      if (override)
      {
        result.getInit().setAccept(false);graphModified = true;
      }
      else
        throw new IllegalArgumentException("incompatible labelling: maximal automaton is all-reject and tentative one is not");     
     
    }

    if (statePair.firstElem.isAccept() == statePair.secondElem.isAccept())
      currentExplorationBoundary.add(statePair);

    Map<String,CmpVertex> emptyTargets = result.createNewRow();
   
    while(!currentExplorationBoundary.isEmpty())
    {
      statePair = currentExplorationBoundary.remove();
      assert graph.transitionMatrix.containsKey(statePair.firstElem) : "state "+statePair.firstElem+" is not known to the first graph";
      assert statePair.secondElem == null || from.transitionMatrix.containsKey(statePair.secondElem) : "state "+statePair.secondElem+" is not known to the second graph";
      assert statePair.secondElem == null || statePair.firstElem.isAccept() == statePair.secondElem.isAccept() : "incompatible labelling of "+statePair;
           
      Map<String,CmpVertex> graphTargets = graph.transitionMatrix.get(statePair.firstElem),
        maxTargets = statePair.secondElem == null? emptyTargets:from.transitionMatrix.get(statePair.secondElem);
      CmpVertex currentRepresentative = pairsToGraphStates.get(statePair);assert currentRepresentative != null;
      for(Entry<String,CmpVertex> labelstate:graphTargets.entrySet())
      {
        String label = labelstate.getKey();
        CmpVertex graphState = labelstate.getValue();// the original one
        CmpVertex maxState = maxTargets.get(label);

        if (maxState == null)
        {// this is the case where a transition in a tentative graph is not matched by any in a maximal automaton
          if (!maxIsPartial)
            throw new IllegalArgumentException("In state pair "+statePair+" transition labelled by "+label+" is not matched in a maximal automaton");
        }
       
        StatePair nextPair = new StatePair(graphState,maxState);
        // Now that we're making a step to a state pair where (graphState,maxState) pair has not been seen before,
        // it is quite possible that we have to clone the corresponding state in a tentative graph so as to ensure
        // that each state from a tentative graph is paired with no more than a single state in a maximal automaton
        // (this corresponds to a construction of a cross-product of states).
        // A state of a tentative state can be unpaired if the maximal automaton is partial,
        // i.e. it contains a number of counter-examples rather than all possible sequences. This is another
        // thing to check for in this method - if taking of an LTL-derived graph this should be deemed an error.
        boolean shouldDescend = true;
        CmpVertex nextGraphVertex = pairsToGraphStates.get(nextPair);// get a state representing the next pair of states
        if (nextGraphVertex == null)
        {// not seen this pair already hence might have to clone.
          if (!encounteredGraph.contains(graphState))
          {// since we did not see this pair before, the first encountered
           // vertex (graphState) is now a representative of the pair nextPair
            nextGraphVertex = AbstractLearnerGraph.cloneCmpVertex(graphState, config);encounteredGraph.add(graphState);
            pairsToGraphStates.put(nextPair,nextGraphVertex);
            result.transitionMatrix.put(nextGraphVertex, result.createNewRow());
            shouldDescend = nextGraphVertex.isAccept();
          }
          else
          {// graphState already paired with one of the states in maximal automaton hence clone the state
            boolean accept = graphState.isAccept() && (maxState == null || maxState.isAccept());// do not descend if the next state is reject or the next state in a maximal automaton is reject
           
            if (graphState.isAccept() != accept)
            {// tentative automaton reaches an accept state but the maximal automaton gets into reject-state
              if (!override)
                throw new IllegalArgumentException("incompatible labelling: maximal automaton chops off some paths in a tentative automaton");
              graphModified=true;
            }
            nextGraphVertex = AbstractLearnerGraph.generateNewCmpVertex(result.nextID(accept), config);
            if (GlobalConfiguration.getConfiguration().isAssertEnabled() && result.findVertex(nextGraphVertex.getID()) != null) throw new IllegalArgumentException("duplicate vertex with ID "+nextGraphVertex.getID()+" in graph "+result);
            DeterministicDirectedSparseGraph.copyVertexData(graphState, nextGraphVertex);nextGraphVertex.setAccept(accept);
            result.transitionMatrix.put(nextGraphVertex,result.createNewRow());
           
            pairsToGraphStates.put(nextPair, nextGraphVertex);
            if (!accept) shouldDescend = false;
          }
        }
        else // already seen the next pair hence no need to descend
          shouldDescend = false;
       
        result.transitionMatrix.get(currentRepresentative).put(label,nextGraphVertex);

        if (shouldDescend)
        // need to explore all transitions from the new state pair.
          currentExplorationBoundary.offer(nextPair);
       
      }
     
      for(Entry<String,CmpVertex> labelstate:maxTargets.entrySet())
      {
        String label = labelstate.getKey();
        if (!graphTargets.containsKey(label) && !labelstate.getValue().isAccept())
        {// a transition in a maximal automaton is not matched but leads to a reject-state hence direct to a reject-state adding it if necessary
          CmpVertex newVert = pairsToGraphStates.get(new StatePair(null,labelstate.getValue()));
          if (newVert == null)
          {
            newVert = result.copyVertexUnderDifferentName(labelstate.getValue());
            pairsToGraphStates.put(new StatePair(null,labelstate.getValue()), newVert);
          }
          result.transitionMatrix.get(currentRepresentative).put(label, newVert);graphModified=true;
        }
      }
    }
View Full Code Here

    CmpVertex stateBig = big.getInit(), stateSmall = small.getInit();
    Map<Pair<CmpVertex,String>,Integer> TX_counter = new HashMap<Pair<CmpVertex,String>,Integer>();// counts transitions which are visited more than once during the traversal.
    Queue<StatePair> currentExplorationBoundary = new LinkedList<StatePair>();// FIFO queue
    int matchedTransitionCounter = 0;
    Set<StatePair> statesAddedToBoundary = new HashSet<StatePair>();
    currentExplorationBoundary.add(new StatePair(stateBig,stateSmall));statesAddedToBoundary.add(new StatePair(stateBig,stateSmall));
    int tx=0;
    while(!currentExplorationBoundary.isEmpty())
    {
      StatePair statePair = currentExplorationBoundary.remove();
      assert big.transitionMatrix.containsKey(statePair.firstElem) : "state "+statePair.firstElem+" is not known to the first graph";
      assert small.transitionMatrix.containsKey(statePair.secondElem) : "state "+statePair.secondElem+" is not known to the second graph";
      if (statePair.firstElem.isAccept() != statePair.secondElem.isAccept())
        throw new DifferentFSMException("states "+statePair.firstElem+" and " + statePair.secondElem+" have a different acceptance labelling between the machines");

      Map<String,CmpVertex> targetsBig = big.transitionMatrix.get(statePair.firstElem);
      Map<String,CmpVertex> targetsSmall = small.transitionMatrix.get(statePair.secondElem);
         
      for(Entry<String,CmpVertex> labelstate:targetsSmall.entrySet())
      {
        String label = labelstate.getKey();
        if (!targetsBig.containsKey(label))
          throw new IllegalArgumentException("small graph is not contained in the large one, from "+statePair+
              " unmatched transition "+label+" to (nothing_in_big,"+labelstate.getValue()+")");
        ++matchedTransitionCounter;
        CmpVertex nextSmall = labelstate.getValue();
        CmpVertex nextBig = targetsBig.get(label);
        Pair<CmpVertex,String> transition = new Pair<CmpVertex,String>(statePair.firstElem,label);
       
        Integer counter = TX_counter.get(transition);
        if (counter == null)
        {
          counter = new Integer(0);
        }
        else ++tx;
        TX_counter.put(transition, counter+1);
        //if (nextBig.equals(statePair.firstElem) &&
        //    !nextSmall.equals(statePair.secondElem))
       
        StatePair nextPair = new StatePair(nextBig,nextSmall);

        if (!statesAddedToBoundary.contains(nextPair))
        {
          currentExplorationBoundary.offer(nextPair);
          statesAddedToBoundary.add(nextPair);
View Full Code Here

  }

  @Test
  public final void testStatePairToString()
  {
    assertEquals("[ A, B ]", new StatePair(AbstractLearnerGraph.generateNewCmpVertex(VertexID.parseID("A"), config),AbstractLearnerGraph.generateNewCmpVertex(VertexID.parseID("B"), config) ).toString());
    assertEquals("[ A, NULL ]", new StatePair(AbstractLearnerGraph.generateNewCmpVertex(VertexID.parseID("A"), config),null ).toString());
    assertEquals("[ NULL, A ]", new StatePair(null,AbstractLearnerGraph.generateNewCmpVertex(VertexID.parseID("A"), config)).toString());
    assertEquals("[ NULL, NULL ]", new StatePair(null,null).toString());
  }
View Full Code Here

TOP

Related Classes of statechum.analysis.learning.StatePair

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.