private void addConclusion(RuleType ruleType, Conclusion conclusion) {
    Set<Conclusion> conclusionSet = conclusions.get(ruleType);
    if (null == conclusionSet) {
      conclusionSet = new TreeSet<Conclusion>();
      conclusions.put(ruleType, conclusionSet);
    }
    conclusionSet.add(conclusion);

    literals.add(conclusion.getLiteral());
  }
  @Override
  public int compareTo(Object o) {
    if (this == o) return 0;

    if (!(o instanceof InferenceLogItem)) getClass().getName().compareTo(o.getClass().getName());

    InferenceLogItem item = (InferenceLogItem) o;
    int c = ruleLabel.compareTo(item.ruleLabel);
    if (c != 0) return c;

    c = ruleInferenceStatuses.size() - item.ruleInferenceStatuses.size();
    if (c != 0) return c;
    if (ruleInferenceStatuses.size() == 0) return 0;

    if (ruleInferenceStatuses.containsKey(RuleType.STRICT)
        && !item.ruleInferenceStatuses.containsKey(RuleType.STRICT)) return Integer.MIN_VALUE;
    if (ruleInferenceStatuses.containsKey(RuleType.DEFEASIBLE)
        && !item.ruleInferenceStatuses.containsKey(RuleType.DEFEASIBLE)) return Integer.MAX_VALUE;

    for (Entry<RuleType, Set<Conclusion>> entry : conclusions.entrySet()) {
      RuleType ruleType = entry.getKey();

      c = ruleInferenceStatuses.get(ruleType).compareTo(item.ruleInferenceStatuses.get(ruleType));
      if (c != 0) return c;

      Set<Conclusion> conclusionSet = entry.getValue();
      Set<Conclusion> iconclusionSet = item.conclusions.get(ruleType);

      c = conclusionSet.size() - iconclusionSet.size();
      if (c != 0) return c;

      Iterator<Conclusion> it = conclusionSet.iterator();
      Iterator<Conclusion> iit = iconclusionSet.iterator();
      while (it.hasNext()) {
        Conclusion cc = it.next();
        Conclusion cci = iit.next();
        c = cc.compareTo(cci);
        if (c != 0) return c;
      }
    }
    return 0;
  }
  private void updateRuleInferenceStatus(
      Conclusion conclusion, RuleType ruleType, RuleInferenceStatus ruleInferenceStatus) {
    if (!ruleInferenceStatuses.containsKey(ruleType)) {
      ruleInferenceStatuses.put(ruleType, ruleInferenceStatus);
    } else {
      RuleInferenceStatus origInferenceStatus = ruleInferenceStatuses.get(ruleType);

      if (conclusion.getLiteral().isPlaceHolder()) {
        switch (conclusion.getConclusionType()) {
          case DEFEASIBLY_NOT_PROVABLE:
          case DEFINITE_NOT_PROVABLE:
            if (origInferenceStatus.compareTo(ruleInferenceStatus) < 0) {
              if (!origInferenceStatus.equals(RuleInferenceStatus.APPICABLE)) {
                ruleInferenceStatuses.put(ruleType, ruleInferenceStatus);
              }
            }
            break;
          default:
            if (origInferenceStatus.compareTo(ruleInferenceStatus) < 0) {
              if (!origInferenceStatus.equals(RuleInferenceStatus.APPICABLE)) {
                ruleInferenceStatuses.put(ruleType, ruleInferenceStatus);
              }
            }
        }
      } else {
        switch (conclusion.getConclusionType()) {
          case DEFEASIBLY_NOT_PROVABLE:
          case DEFINITE_NOT_PROVABLE:
            if (origInferenceStatus.compareTo(ruleInferenceStatus) > 0) {
              ruleInferenceStatuses.put(ruleType, ruleInferenceStatus);
            }
            break;
          default:
            if (origInferenceStatus.compareTo(ruleInferenceStatus) < 0) {
              ruleInferenceStatuses.put(ruleType, ruleInferenceStatus);
            }
            // ruleInferenceStatuses.put(ruleType, ruleInferenceStatus);
        }
      }
    }
  }
 public void addRuleInfernceItem(Conclusion conclusion, RuleInferenceStatus ruleInferenceStatus) {
   RuleType ruleType = getRuleType(conclusion.getConclusionType());
   addConclusion(ruleType, conclusion);
   updateRuleInferenceStatus(conclusion, ruleType, ruleInferenceStatus);
 }
 public boolean contains(Conclusion conclusion) {
   RuleType ruleType = getRuleType(conclusion.getConclusionType());
   if (!conclusions.containsKey(ruleType)) return false;
   return conclusions.get(ruleType).contains(conclusion);
 }