public static MyBooleanExpression get(String repr) throws ParseException {
    if (expressions.containsKey(repr)) {
      return expressions.get(repr);
    }
    MyBooleanExpression newExpr = new MyBooleanExpression(repr);
    for (MyBooleanExpression oldExpr : expressions.values()) {
      if (oldExpr.equals(newExpr)) {
        expressions.put(repr, oldExpr);
        return oldExpr;
      }
    }

    expressions.put(repr, newExpr);
    return newExpr;
  }
  public boolean equals(MyBooleanExpression other) {
    if (other.repr.equals(this.repr)) {
      return true;
    }

    // possible to rewrite in a smarter way
    MyBooleanExpression e = null;
    try {
      e = new MyBooleanExpression("(" + this.repr + ")=(" + other.repr + ")");
    } catch (ParseException ex) {
      ex.printStackTrace();
      System.exit(1);
    }
    /*
    if (e.isTautology()) {
        System.out.println(e + "    " + e.isTautology());
        System.out.println(e.satisfiabilitySetsCount);
    }
    */
    return e.isTautology();
  }
  public boolean hasSolutionWith(MyBooleanExpression other) {
    if (hasSolutionWithRes == null) {
      hasSolutionWithRes = new HashMap<>();
    }

    if (hasSolutionWithRes.containsKey(other)) {
      return hasSolutionWithRes.get(other);
    }

    // possible to rewrite in a smarter way
    MyBooleanExpression e = null;
    try {
      e = new MyBooleanExpression("(" + repr + ")&(" + other.repr + ")");
    } catch (ParseException ex) {
      ex.printStackTrace();
      System.exit(1);
    }
    boolean res = e.hasSolution();
    hasSolutionWithRes.put(other, res);
    return res;
  }
  public TestsModelCheckingTaskWithConsistencyGraph(AbstractTaskConfig config) {
    super(config);
    FSM.setEvents(events);

    for (int i = 0; i < events.size(); i++) {
      eventsMap.put(events.get(i), i);
    }

    scenarioTree = new ScenariosTree();
    try {
      scenarioTree.load("sc");
    } catch (FileNotFoundException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    } catch (ParseException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }

    consistencyGraph = AdjacentCalculator.getAdjacent(scenarioTree);

    consistencyGraphBoolean = new boolean[consistencyGraph.size()][consistencyGraph.size()];
    hasInconsistency = new boolean[consistencyGraph.size()];

    Arrays.fill(hasInconsistency, false);
    for (int i = 0; i < consistencyGraph.size(); i++) {
      Arrays.fill(consistencyGraphBoolean[i], false);
    }

    for (Node n1 : consistencyGraph.keySet()) {
      for (Node n2 : consistencyGraph.get(n1)) {
        consistencyGraphBoolean[n1.getNumber()][n2.getNumber()] = true;
        consistencyGraphBoolean[n2.getNumber()][n1.getNumber()] = true;
      }
    }

    for (int i = 0; i < consistencyGraph.size(); i++) {
      for (int j = 0; j < consistencyGraph.size(); j++) {
        if (consistencyGraphBoolean[i][j]) {
          hasInconsistency[i] = true;
          break;
        }
      }
    }

    for (AutomatonTest test : tests) {
      for (String s : test.getInput()) {
        String[] eventGuard = s.split("\\[");
        String event = eventGuard[0].trim();
        efPairToEvent.put(s, event);

        MyBooleanExpression guard = null;

        try {
          if (eventGuard.length > 1) {
            guard = MyBooleanExpression.get(eventGuard[1].replace("]", "").trim());
          } else {
            guard = MyBooleanExpression.get("1");
          }
        } catch (ParseException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
        }
        efPairToBooleanExpression.put(s, guard);
      }
    }

    //		try {
    //			out = new PrintWriter(new File("tests-consistency-scatter"));
    //		} catch (FileNotFoundException e) {
    //			e.printStackTrace();
    //		}
  }