Program: 42149
Project: 42149
Buggy source:
/** 
 * judge whether <code>sft1withEps</code> and <code>sft2withEps</code> are 1-equality (partial equivalent) Page 6, in the middle of left column, figure 3
 * @param sft1withEps symbolic finite transducer 1 who may have epsilon transitions
 * @param sft2withEps symbolic finite transducer 2 who may have epsilon transitions
 */
public static <P,F,S>boolean decide1equality(SFT<P,F,S> sft1withEps,SFT<P,F,S> sft2withEps,BooleanAlgebraSubst<P,F,S> ba) throws TimeoutException {
  SFTProduct<P,F,S> product=SFTProduct.MkSFTProduct(sft1withEps,sft2withEps,ba);
  HashMap<Integer,Pair<List<S>,List<S>>> reached=new HashMap<Integer,Pair<List<S>,List<S>>>();
  reached.put(product.getInitialState(),new Pair(new ArrayList<S>(),new ArrayList<S>()));
  LinkedList<Integer> toVisit=new LinkedList<Integer>();
  toVisit.add(product.getInitialState());
  while (!toVisit.isEmpty()) {
    Integer currState=toVisit.pop();
    Pair<List<S>,List<S>> promise=reached.get(currState);
    for (    SFTProductInputMove transition : product.getInputMovesFrom(currState)) {
      List<F> u=new ArrayList<F>();
      List<F> v=new ArrayList<F>();
      for (      S a : promise.first)       u.add(ba.MkFuncConst(a));
      for (      S b : promise.second)       v.add(ba.MkFuncConst(b));
      u.addAll(transition.outputFunctions1);
      v.addAll(transition.outputFunctions2);
      if (product.isFinalState(currState)) {
        Set<List<S>> tails1=checkNotNull(product.getFinalStatesAndTails().get(currState).first);
        Set<List<S>> tails2=checkNotNull(product.getFinalStatesAndTails().get(currState).second);
        if (tails1.size() > 1 || tails2.size() > 1)         return false;
        List<F> finalU=new ArrayList<F>(u);
        List<F> finalV=new ArrayList<F>(v);
        for (        List<S> tail : tails1)         for (        S element : tail)         finalU.add(ba.MkFuncConst(element));
        for (        List<S> tail : tails2)         for (        S element : tail)         finalV.add(ba.MkFuncConst(element));
        if (finalU.size() != finalV.size())         return false;
        for (int i=0; i < finalU.size(); i++)         if (!ba.CheckGuardedEquality((P)transition.guard,finalU.get(i),finalV.get(i)))         return false;
      }
      if (u.size() >= v.size()) {
        for (int i=0; i < v.size(); i++)         if (!ba.CheckGuardedEquality((P)transition.guard,u.get(i),v.get(i)))         return false;
        List<F> w=new ArrayList<F>();
        for (int i=v.size(); i < u.size(); i++)         w.add(u.get(i));
        S witness=(S)transition.getWitness(ba);
        List<S> c=new ArrayList<S>();
        List<F> cF=new ArrayList<F>();
        for (int i=0; i < u.size() - v.size(); i++) {
          c.add(ba.MkSubstFuncConst(w.get(i),witness));
          cF.add(ba.MkSubstFuncFunc(w.get(i),ba.MkFuncConst(witness)));
        }
        for (int i=0; i < u.size() - v.size(); i++)         if (!ba.AreEquivalent(ba.MkSubstFuncPred(w.get(i),(P)transition.guard),ba.MkSubstFuncPred(cF.get(i),(P)transition.guard)))         return false;
        if (reached.containsKey(currState) && !reached.get(currState).equals(new Pair(c,new ArrayList<S>())))         return false;
        if (!reached.containsKey(currState)) {
          toVisit.push(currState);
          reached.put(currState,new Pair(c,new ArrayList<S>()));
        }
      }
 else {
        for (int i=0; i < u.size(); i++)         if (!ba.CheckGuardedEquality((P)transition.guard,u.get(i),v.get(i)))         return false;
        List<F> w=new ArrayList<F>();
        for (int i=u.size(); i < v.size(); i++)         w.add(v.get(i));
        S witness=(S)transition.getWitness(ba);
        List<S> c=new ArrayList<S>();
        List<F> cF=new ArrayList<F>();
        for (int i=0; i < v.size() - u.size(); i++) {
          c.add(ba.MkSubstFuncConst(w.get(i),witness));
          cF.add(ba.MkSubstFuncFunc(w.get(i),ba.MkFuncConst(witness)));
        }
        for (int i=0; i < v.size() - u.size(); i++)         if (!ba.AreEquivalent(ba.MkSubstFuncPred(w.get(i),(P)transition.guard),ba.MkSubstFuncPred(cF.get(i),(P)transition.guard)))         return false;
        if (reached.containsKey(currState) && !reached.get(currState).equals(new Pair(new ArrayList<S>(),c)))         return false;
        if (!reached.containsKey(currState)) {
          toVisit.push(currState);
          reached.put(currState,new Pair(new ArrayList<S>(),c));
        }
      }
    }
  }
  return true;
}

Fixed version (ground truth):
/** 
 * judge whether <code>sft1withEps</code> and <code>sft2withEps</code> are 1-equality (partial equivalent) Page 6, in the middle of left column, figure 3
 * @param sft1withEps symbolic finite transducer 1 who may have epsilon transitions
 * @param sft2withEps symbolic finite transducer 2 who may have epsilon transitions
 */
public static <P,F,S>boolean decide1equality(SFT<P,F,S> sft1withEps,SFT<P,F,S> sft2withEps,BooleanAlgebraSubst<P,F,S> ba) throws TimeoutException {
  SFTProduct<P,F,S> product=SFTProduct.MkSFTProduct(sft1withEps,sft2withEps,ba);
  HashMap<Integer,Pair<List<S>,List<S>>> reached=new HashMap<Integer,Pair<List<S>,List<S>>>();
  reached.put(product.getInitialState(),new Pair(new ArrayList<S>(),new ArrayList<S>()));
  LinkedList<Integer> toVisit=new LinkedList<Integer>();
  toVisit.add(product.getInitialState());
  while (!toVisit.isEmpty()) {
    Integer currState=toVisit.pop();
    Pair<List<S>,List<S>> promise=reached.get(currState);
    for (    SFTProductInputMove transition : product.getInputMovesFrom(currState)) {
      List<F> u=new ArrayList<F>();
      List<F> v=new ArrayList<F>();
      for (      S a : promise.first)       u.add(ba.MkFuncConst(a));
      for (      S b : promise.second)       v.add(ba.MkFuncConst(b));
      u.addAll(transition.outputFunctions1);
      v.addAll(transition.outputFunctions2);
      if (product.isFinalState(currState)) {
        Set<List<S>> tails1=checkNotNull(product.getFinalStatesAndTails().get(currState).first);
        Set<List<S>> tails2=checkNotNull(product.getFinalStatesAndTails().get(currState).second);
        if (tails1.size() > 1 || tails2.size() > 1)         return false;
        List<F> finalU=new ArrayList<F>(u);
        List<F> finalV=new ArrayList<F>(v);
        for (        List<S> tail : tails1)         for (        S element : tail)         finalU.add(ba.MkFuncConst(element));
        for (        List<S> tail : tails2)         for (        S element : tail)         finalV.add(ba.MkFuncConst(element));
        if (finalU.size() != finalV.size())         return false;
        for (int i=0; i < finalU.size(); i++)         if (!ba.CheckGuardedEquality((P)transition.guard,finalU.get(i),finalV.get(i)))         return false;
      }
      if (u.size() >= v.size()) {
        for (int i=0; i < v.size(); i++)         if (!ba.CheckGuardedEquality((P)transition.guard,u.get(i),v.get(i)))         return false;
        List<F> w=new ArrayList<F>();
        for (int i=v.size(); i < u.size(); i++)         w.add(u.get(i));
        S witness=(S)transition.getWitness(ba);
        List<S> c=new ArrayList<S>();
        List<F> cF=new ArrayList<F>();
        for (int i=0; i < u.size() - v.size(); i++) {
          c.add(ba.MkSubstFuncConst(w.get(i),witness));
          cF.add(ba.MkSubstFuncFunc(w.get(i),ba.MkFuncConst(witness)));
        }
        for (int i=0; i < u.size() - v.size(); i++)         if (!ba.AreEquivalent(ba.MkSubstFuncPred(w.get(i),(P)transition.guard),ba.MkSubstFuncPred(cF.get(i),(P)transition.guard)))         return false;
        Integer nextState=transition.to;
        if (reached.containsKey(nextState) && !reached.get(nextState).equals(new Pair(c,new ArrayList<S>())))         return false;
        if (!reached.containsKey(nextState)) {
          toVisit.push(nextState);
          reached.put(nextState,new Pair(c,new ArrayList<S>()));
        }
      }
 else {
        for (int i=0; i < u.size(); i++)         if (!ba.CheckGuardedEquality((P)transition.guard,u.get(i),v.get(i)))         return false;
        List<F> w=new ArrayList<F>();
        for (int i=u.size(); i < v.size(); i++)         w.add(v.get(i));
        S witness=(S)transition.getWitness(ba);
        List<S> c=new ArrayList<S>();
        List<F> cF=new ArrayList<F>();
        for (int i=0; i < v.size() - u.size(); i++) {
          c.add(ba.MkSubstFuncConst(w.get(i),witness));
          cF.add(ba.MkSubstFuncFunc(w.get(i),ba.MkFuncConst(witness)));
        }
        for (int i=0; i < v.size() - u.size(); i++)         if (!ba.AreEquivalent(ba.MkSubstFuncPred(w.get(i),(P)transition.guard),ba.MkSubstFuncPred(cF.get(i),(P)transition.guard)))         return false;
        Integer nextState=transition.to;
        if (reached.containsKey(nextState) && !reached.get(nextState).equals(new Pair(new ArrayList<S>(),c)))         return false;
        if (!reached.containsKey(nextState)) {
          toVisit.push(nextState);
          reached.put(nextState,new Pair(new ArrayList<S>(),c));
        }
      }
    }
  }
  return true;
}