Package statechum.analysis.learning

Examples of statechum.analysis.learning.StatePair


    assert stateExpectedArg != null && stateActualArg != null;
    CmpVertex stateActual = stateActualArg, stateExpected = stateExpectedArg;
   
    Queue<StatePair> currentExplorationBoundary = new LinkedList<StatePair>();// FIFO queue
    CollectionOfPairs statesAddedToBoundary = new CollectionOfPairs(graphMoreGeneral,graphLessGeneral);
    currentExplorationBoundary.add(new StatePair(stateExpected,stateActual));statesAddedToBoundary.addAndCheck(new StatePair(stateExpected,stateActual));
 
    CmpVertex sink = generateSinkState(graphMoreGeneral);
    Map<Label, CmpVertex> sinkRow = graphMoreGeneral.createNewRow();
    while(!currentExplorationBoundary.isEmpty())
    {
      StatePair statePair = currentExplorationBoundary.remove();
      assert statePair.firstElem == sink || graphMoreGeneral.transitionMatrix.containsKey(statePair.firstElem) : "state "+statePair.firstElem+" is not known to the expected graph";
      assert statePair.secondElem == sink || graphLessGeneral.transitionMatrix.containsKey(statePair.secondElem) : "state "+statePair.secondElem+" is not known to the actual graph";
      if (statePair.firstElem.isAccept() != statePair.secondElem.isAccept())
        return new DifferentFSMException("states "+statePair.firstElem+" and " + statePair.secondElem+" have a different acceptance labelling between the machines");
 
      Map<Label,CmpVertex> moreGeneralTargets = statePair.firstElem == sink?sinkRow:graphMoreGeneral.transitionMatrix.get(statePair.firstElem);
      Map<Label,CmpVertex> lessGeneralTargets = statePair.secondElem == sink?sinkRow:graphLessGeneral.transitionMatrix.get(statePair.secondElem);
      //if (prefixClosed && expectedTargets.size() != actualTargets.size())// each of them is equal to the keyset size from determinism
      //  return new DifferentFSMException("different number of transitions from states "+statePair);
      Set<Label> outgoingAll = new TreeSet<Label>();outgoingAll.addAll(moreGeneralTargets.keySet());outgoingAll.addAll(lessGeneralTargets.keySet());
      for(Label label:outgoingAll)
      {
        CmpVertex nextExpectedState = null;
        if (!moreGeneralTargets.containsKey(label))
          return new DifferentFSMException("no transition with expected label \""+label+"\" from a state \""+statePair.secondElem+"\" corresponding to \""+statePair.firstElem+"\"");
        nextExpectedState = moreGeneralTargets.get(label);
       
        CmpVertex nextActualState = null;
        if (!lessGeneralTargets.containsKey(label))
          nextActualState = sink; 
        else
        {// only explore where both can take a transition
          nextActualState = lessGeneralTargets.get(label);
 
          StatePair nextPair = new StatePair(nextExpectedState,nextActualState);
          //System.out.println("outgoing: "+statePair.getR()+","+statePair.getQ()+"-"+label+"->"+nextPair.getR()+","+nextPair.getQ());// elements of the pairs are in reverse order
          if (statesAddedToBoundary.addAndCheck(nextPair))
            currentExplorationBoundary.offer(nextPair);
        }
      }
View Full Code Here


     
      // Special configuration is necessary to ensure that computePairCompatibilityScore_internal
      // builds mergedVertices using g's vertices rather than StringVertices or clones of g's vertices.
      Configuration VertexCloneConf = conf.copy();VertexCloneConf.setLearnerUseStrings(false);VertexCloneConf.setLearnerCloneGraph(false);
      LearnerGraph s=new LearnerGraph(g,VertexCloneConf);
      if (s.pairscores.computePairCompatibilityScore_internal(new StatePair(s.findVertex(pair.getQ()),s.findVertex(pair.getR())),mergedVertices) < 0)
        throw new IllegalArgumentException("elements of the pair are incompatible");

      // make a loop
      Set<Label> usedInputs = new HashSet<Label>();
      for(DirectedSparseEdge e:(Set<DirectedSparseEdge>)newBlue.getInEdges())
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<Label,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<Label,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<Label,CmpVertex> labelstate:graphTargets.entrySet())
      {
        Label 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) != null) throw new IllegalArgumentException("duplicate vertex with ID "+nextGraphVertex.getStringId()+" 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<Label,CmpVertex> labelstate:maxTargets.entrySet())
      {
        Label 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,Label>,Integer> TX_counter = new HashMap<Pair<CmpVertex,Label>,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<Label,CmpVertex> targetsBig = big.transitionMatrix.get(statePair.firstElem);
      Map<Label,CmpVertex> targetsSmall = small.transitionMatrix.get(statePair.secondElem);
         
      for(Entry<Label,CmpVertex> labelstate:targetsSmall.entrySet())
      {
        Label 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,Label> transition = new Pair<CmpVertex,Label>(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

                    synchronized (currentExplorationBoundary)
                    {
                      if (!sourceData.contains(sourcePair))
                      {
                        sourceData.add(sourcePair);
                        currentExplorationBoundary.add(new StatePair(srcB,srcA));
                      }
                    }
                  }
              }
            }
          }// if intersects
          else
            if (incompatiblePairs[currentStatePair] != PAIR_INCOMPATIBLE) // it is not possible for this loop to set this -
              // we are going through the vertices sequentially, but it could have been set by whoever called us.
            incompatiblePairs[currentStatePair]=PAIR_OK;// potentially compatible pair

          if (stateB.getKey().equals(entryA.getKey())) break; // we only process a triangular subset.
        }// B-loop
      }
    });
    performRowTasks(handlerList, ThreadNumber, matrixForward.transitionMatrix, filter,
        GDLearnerGraph.partitionWorkLoadTriangular(ThreadNumber,matrixForward.transitionMatrix.size()));
    //inputsAccepted=null;inputsRejected=null;
   
    // At this point, we've marked all clearly incompatible pairs of states and need to propagate
    // this information further, to states which have transitions leading to the currently considered set of states.
    // This part is not run in parallel on multiple CPUs (we expect it to do little most of the time),
    // hence no need to split the processing and/or lock currentExplorationBoundary
    while(!currentExplorationBoundary.isEmpty())
    {
      StatePair pair = currentExplorationBoundary.remove();
     
      int currentStatePair = vertexToIntNR(pair.firstElem,pair.secondElem);
      incompatiblePairs[currentStatePair]=PAIR_INCOMPATIBLE;

      Map<Label,List<CmpVertex>> rowB = matrixInverse.transitionMatrix.get(pair.secondElem);
     
      for(Entry<Label,List<CmpVertex>> outLabel:matrixInverse.transitionMatrix.get(pair.firstElem).entrySet())
      {
        List<CmpVertex> to = rowB.get(outLabel.getKey());
        if (to != null)
        {// matched pair of transitions, now we need to build a cross-product
         // of the states leading to the current pair of states, that is,
         // to (entryA.getKey(),stateB)
          for(CmpVertex srcA:outLabel.getValue())
            for(CmpVertex srcB:to)
            {
              // It is possible that for the same inputs (srcA,srcB)=(A,B) and (B,A)
              // in this case, we have to avoid including (B,A) in the list, but
              // it is not known in advance if any such case occurs, so we have to store
              // the pairs we encountered and eliminate them. Happily, this is handled by
              // incompatiblePairs[sourcePair]=PAIR_INCOMPATIBLE
              int sourcePair = vertexToIntNR(srcA, srcB);
              if (incompatiblePairs[sourcePair] == PAIR_OK)
              {
                currentExplorationBoundary.offer(new StatePair(srcA,srcB)); // append to the list
                incompatiblePairs[sourcePair]=PAIR_INCOMPATIBLE;
              }
            }
        }
      }
View Full Code Here

  }
 
  protected PairScore obtainPair(CmpVertex blue, CmpVertex red)
  {
    if (coregraph.learnerCache.maxScore < 0) coregraph.learnerCache.maxScore = coregraph.transitionMatrix.size()*coregraph.pathroutines.computeAlphabet().size();
    long computedScore = -1, compatibilityScore =-1;StatePair pairToComputeFrom = new StatePair(blue,red);
    if (coregraph.config.getLearnerScoreMode() == Configuration.ScoreMode.COMPATIBILITY)
    {
      computedScore = computePairCompatibilityScore(pairToComputeFrom);compatibilityScore=computedScore;
    }
    else   
View Full Code Here

    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.

      if (!AbstractLearnerGraph.checkCompatible(currentPair.getQ(),currentPair.getR(),coregraph.pairCompatibility))
        return -1;// incompatible states
      if (!redFromPta.booleanValue())
        ++score;
      Map<Label,CmpVertex> targetBlue = coregraph.transitionMatrix.get(currentPair.getQ());

      for(Entry<Label,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
          boolean newRedFromPta = redFromPta;
         
          // 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
            newRedFromPta = 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).
          }

          if (coregraph.config.getScoreCompatibilityScoreComputationBugEmulation())
            redFromPta = newRedFromPta;
          StatePair nextStatePair = new StatePair(blueEntry.getValue(),nextRedState);
          currentExplorationBoundary.offer(nextStatePair);currentRedFromPta.offer(newRedFromPta);
        }
        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

  }

  @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

   */
  @Test
  public final void testStatePairEquality()
  {
    final Object samePairs[] = new StatePair[]{
        new StatePair(new StringVertex("a"), new StringVertex("b")),
        new StatePair(new DeterministicVertex("a"), new StringVertex("b")),
        new StatePair(new StringVertex("a"), new DeterministicVertex("b")),
        new StatePair(new DeterministicVertex("a"), new DeterministicVertex("b"))       
    },
    differentPairs[] = new Object[] {
        new StatePair(new StringVertex("a"), new StringVertex("c")),
        new StatePair(new StringVertex("d"), new StringVertex("b")),
        new StatePair(new StringVertex("d"), new StringVertex("e")),
        constructOrigPair("a", "b")
    };
    for(int sameFirst=0;sameFirst<samePairs.length;++sameFirst)
      for(int sameSecond=0;sameSecond<samePairs.length;++sameSecond)
        for(int different=0;different<differentPairs.length;++different)
View Full Code Here

 
  /** Tests that nulls are valid elements of state pairs. */
  public final void testStatePairEqualityWithNulls1()
  {
    final Object samePairs[] = new StatePair[]{
        new StatePair(null, new StringVertex("b")),
        new StatePair(null, new DeterministicVertex("b"))     
    },
    differentPairs[] = new Object[] {
        new StatePair(new StringVertex("b"), new StringVertex("b")),
        new StatePair(new DeterministicVertex("b"), new StringVertex("b")),
        new StatePair(null, null),
        constructOrigPair("a", "b")
    };
    for(int sameFirst=0;sameFirst<samePairs.length;++sameFirst)
      for(int sameSecond=0;sameSecond<samePairs.length;++sameSecond)
        for(int different=0;different<differentPairs.length;++different)
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.