public AllSubstitution FOL_BC_AND(List<Predicate> goal, AllSubstitution theta) {
    //
    if (theta.status == false) return theta;
    else if (goal.size() == 0) return theta;
    else {
      Predicate first = goal.get(0); // n

      first = substFromTheata(theta, first);

      int index = 0;

      int tSize =
          (KBObj.KB.get(first.fnName) == null)
              ? 0
              : (KBObj.KB.get(first.fnName).sentences.size() - 1);
      while (index <= tSize) {
        AllSubstitution thetaPrime = FOL_BC_OR(first, theta, index++);

        if (thetaPrime.status && goal.size() > 1) {
          List<Predicate> rest =
              new ArrayList<Predicate>(((ArrayList<Predicate>) goal).subList(1, goal.size()));

          AllSubstitution thetaDoublePrime = FOL_BC_AND(rest, sumUpTheta(theta, thetaPrime));

          if (thetaDoublePrime.status) return thetaDoublePrime;
        } else return thetaPrime;
      }
      AllSubstitution t = new AllSubstitution();
      t.status = false;
      return t;
    }
  }
  public AllSubstitution FOL_BC_OR(Predicate goal, AllSubstitution theta, int index) {
    // the key is the function name of query. H(x), H is key.
    String key = goal.fnName;

    // get all the sentence which has conclusion as goal.
    List<Sentence> sents = (KBObj.KB.get(key) == null) ? null : KBObj.KB.get(key).sentences;
    if (sents != null) {
      // Iterate through all the sentence which have conclusion as sentence.
      // for (Sentence sentence : sents) {
      for (int i = index; i < sents.size(); i++) {
        Sentence sentence = sents.get(i);
        AllSubstitution subst = UNIFY(sentence.rhs, goal, sentence);

        AllSubstitution thetaPrime = FOL_BC_AND(sentence.lhs, subst);
        if (thetaPrime != null && thetaPrime.status) {
          return thetaPrime;
        }
      }
    }
    AllSubstitution t = new AllSubstitution();
    t.status = false;
    return t;
  }