/**
   * Compute invariants of a graph g by mining invariants from the transitive closure using {@code
   * extractInvariantsUsingTC}, which returns an over-approximation of the invariants that hold
   * (i.e. it may return invariants that do not hold, but may not fail to return an invariant that
   * does not hold)
   *
   * @param g the graph of nodes of type LogEvent
   * @param mineConcurrencyInvariants whether or not to also mine concurrency invariants
   * @return the set of temporal invariants the graph satisfies
   */
  public TemporalInvariantSet computeTransClosureInvariants(
      TraceGraph<?> g, boolean mineConcurrencyInvariants) {

    TimedTask mineInvariants = PerformanceMetrics.createTask("mineInvariants", false);
    Set<ITemporalInvariant> overapproximatedInvariantsSet;

    AbstractMain main = AbstractMain.getInstance();

    // Compute the over-approximated set of invariants for the input graph.
    try {

      TimedTask itc = PerformanceMetrics.createTask("invariants_transitive_closure", false);

      // Compute the transitive closure.
      AllRelationsTransitiveClosure transitiveClosure = new AllRelationsTransitiveClosure(g);

      // Get the over-approximation.
      itc.stop();
      if (main.options.doBenchmarking) {
        logger.info("BENCHM: " + itc);
      }
      TimedTask io = PerformanceMetrics.createTask("invariants_approximation", false);

      // Extract invariants for all relations, iteratively. Since we are
      // not considering invariants over multiple relations, this is
      // sufficient.
      overapproximatedInvariantsSet = new LinkedHashSet<ITemporalInvariant>();
      for (String relation : g.getRelations()) {
        overapproximatedInvariantsSet.addAll(
            extractInvariantsFromTC(
                g, transitiveClosure.get(relation), relation, mineConcurrencyInvariants));
      }

      io.stop();
      if (main.options.doBenchmarking) {
        logger.info("BENCHM: " + io);
      }
      // logger.info("Over-approx set: "
      // + overapproximatedInvariantsSet.toString());
    } finally {
      mineInvariants.stop();
    }

    return new TemporalInvariantSet(overapproximatedInvariantsSet);
  }
 public AllRelationsTransitiveClosure(TraceGraph<?> g) {
   for (String relation : g.getRelations()) {
     tcs.put(relation, g.getTransitiveClosure(relation));
   }
 }