@Test
 public void testToCNFClauses_empty() {
   Formula f = new Formula();
   assertTrue(f.toCNFClauses().isEmpty() == true);
 }
  @Test
  public void testToCNFClauses() {
    Var a = new Var("a");
    Var b = new Var("b");
    Var c = new Var("c");
    Var d = new Var("d");

    Formula f = a.or(b).or(c).or(d);
    assertTrue("a or b or c or d".equals(f.toCNF().toString()));
    List<Clause> clauses = f.toCNFClauses();
    assertTrue(clauses.size() == 1);
    assertTrue("a or b or c or d".equals(clauses.get(0).toString()));

    f = (a.and(b)).or(c.and(d));
    assertTrue("(a or c) and (b or c) and (a or d) and (b or d)".equals(f.toCNF().toString()));
    clauses = f.toCNFClauses();
    assertTrue(clauses.size() == 4);
    assertTrue(clauses.contains(new Clause(a.or(c))));
    assertTrue(clauses.contains(new Clause(b.or(c))));
    assertTrue(clauses.contains(new Clause(a.or(d))));
    assertTrue(clauses.contains(new Clause(b.or(d))));

    f = (a.and(b)).or(c).or(d);
    assertTrue("(a or c or d) and (b or c or d)".equals(f.toCNF().toString()));
    clauses = f.toCNFClauses();
    assertTrue(clauses.size() == 2);
    assertTrue(clauses.contains(new Clause(a.or(c).or(d))));
    assertTrue(clauses.contains(new Clause(b.or(c).or(d))));

    f = ((a.and(b)).or(c).or(d)).not();
    assertTrue("(!a or !b) and !c and !d".equals(f.toCNF().toString()));
    clauses = f.toCNFClauses();
    assertTrue(clauses.size() == 3);
    assertTrue(clauses.contains(new Clause((a.not()).or(b.not()))));
    assertTrue(clauses.contains(new Clause(c.not())));
    assertTrue(clauses.contains(new Clause(d.not())));

    f = (a).not().not().not().not().not().not();
    assertTrue("a".equals(f.toCNF().toString()));
    clauses = f.toCNFClauses();
    assertTrue(clauses.size() == 1);
    assertTrue(clauses.contains(new Clause(a)));

    f = (a).not().not().not().not().not();
    assertTrue("!a".equals(f.toCNF().toString()));
    clauses = f.toCNFClauses();
    assertTrue(clauses.size() == 1);
    assertTrue(clauses.contains(new Clause(a.not())));

    f = ((a).and(b)).or((a).not().and(c)).or(((b).not()).and((c).not()));
    assertTrue(
        "(a or !a or !b) and (b or !a or !b) and (a or c or !b) and (b or c or !b) and (a or !a or !c) and (b or !a or !c) and (a or c or !c) and (b or c or !c)"
            .equals(f.toCNF().toString()));
    clauses = f.toCNFClauses();
    assertTrue(clauses.size() == 8);
    assertTrue(clauses.contains(new Clause(a.or(a.not()).or(b.not()))));
    assertTrue(clauses.contains(new Clause(b.or(a.not()).or(b.not()))));
    assertTrue(clauses.contains(new Clause(a.or(c).or(b.not()))));
    assertTrue(clauses.contains(new Clause(b.or(c).or(b.not()))));
    assertTrue(clauses.contains(new Clause(a.or(a.not()).or(c.not()))));
    assertTrue(clauses.contains(new Clause(b.or(a.not()).or(c.not()))));
    assertTrue(clauses.contains(new Clause(a.or(c).or(c.not()))));
    assertTrue(clauses.contains(new Clause(b.or(c).or(c.not()))));
  }