func TestCombine(t *testing.T) {
	empty, one, two, three := clause.ConstructTestClauses()
	cs0 := ClauseSet{}

	cs1 := ClauseSet{}
	cs1.Append(empty)

	cs2 := ClauseSet{}
	cs2.Append(one)

	cs3 := ClauseSet{}
	cs3.Append(two)
	cs3.Append(three)

	cases := []struct {
		a    ClauseSet
		b    ClauseSet
		want string
	}{
		{cs0, cs0, "{}"},
		{cs0, cs1, "{{}}"},
		{cs1, cs1, "{{}}"},
		{cs1, cs2, "{{}, {A}}"},
		{cs2, cs2, "{{A}}"},
		{cs2, cs3, "{{A}, {A, B}, {A, B, ~B}}"},
	}
	for _, clause := range cases {
		got := Combine(clause.a, clause.b).String()
		if got != clause.want {
			t.Errorf("Combine(%q, %q): %q != %q", clause.a, clause.b, got, clause.want)
		}
	}
}
func TestFirstElement(t *testing.T) {
	empty, one, _, _ := clause.ConstructTestClauses()

	//case0 -- emptyClauseSet
	cs := ClauseSet{}
	got, err := cs.FirstElement()
	want := clause.Clause{}

	if !clause.Equals(got, want) || err == nil {
		t.Errorf("%q.FirstElement() == %q, want %q (error: %q)", cs, got, want, err)
	}

	//case1 -- one thing
	cs = ClauseSet{}
	cs.Append(empty)
	got, err = cs.FirstElement()
	want = clause.Clause{}

	if !clause.Equals(got, want) || err != nil {
		t.Errorf("%q.FirstElement() == %q, want %q (error: %q)", cs, got, want, err)
	}

	//case2 -- two things
	cs = ClauseSet{}
	cs.Append(one)
	cs.Append(empty)
	got, err = cs.FirstElement()
	want = clause.Clause{}

	if !clause.Equals(got, want) || err != nil {
		t.Errorf("%q.FirstElement() == %q, want %q (error: %q)", cs, got, want, err)
	}
}
func TestNextLiteral(t *testing.T) {
	empty, one, _, _ := clause.ConstructTestClauses()

	//case0 -- emptyClauseSet
	cs := ClauseSet{}
	got, err := cs.NextLiteral()
	want := literal.Literal{}
	if !literal.Equals(got, want) || err == nil {
		t.Errorf("%q.FirstElement() == %q, want %q (error: %q)", cs, got, want, err)
	}

	//case1 -- empty clause in emptyClauseSet
	cs = ClauseSet{}
	cs.Append(empty)
	got, err = cs.NextLiteral()
	want = literal.Literal{}
	if !literal.Equals(got, want) || err == nil {
		t.Errorf("%q.FirstElement() == %q, want %q (error: %q)", cs, got, want, err)
	}

	//case2 -- one clause in emptyClauseSet
	cs = ClauseSet{}
	cs.Append(one)
	got, err = cs.NextLiteral()
	want = literal.Literal{"A", false}
	if !literal.Equals(got, want) || err != nil {
		t.Errorf("%q.FirstElement() == %q, want %q (error: %q)", cs, got, want, err)
	}

}
func TestPrint(t *testing.T) {
	_, one, two, three := clause.ConstructTestClauses()

	//case0 -- empty ClauseSet
	cs := ClauseSet{}
	got := cs.String()
	want := "{}"
	if got != want {
		t.Errorf("String() == %q, want %q", got, want)
	}

	//case1 -- 1 thing in ClauseSet
	cs = ClauseSet{}
	cs.Append(one)
	got = cs.String()
	want = "{{A}}"
	if got != want {
		t.Errorf("String() == %q, want %q", got, want)
	}

	//case2-- 2 things in ClauseSet
	cs = ClauseSet{}
	cs.Append(one)
	cs.Append(two)
	got = cs.String()
	want = "{{A}, {A, B}}"
	if got != want {
		t.Errorf("String() == %q, want %q", got, want)
	}

	//case3-- 3 things in ClauseSet
	cs = ClauseSet{}
	cs.Append(one)
	cs.Append(two)
	cs.Append(three)
	got = cs.String()
	want = "{{A}, {A, B}, {A, B, ~B}}"
	if got != want {
		t.Errorf("String() == %q, want %q", got, want)
	}

}
func TestCopy(t *testing.T) {
	_, one, two, _ := clause.ConstructTestClauses()

	//case0 -- empty ClauseSet, don't change
	cs := ClauseSet{}
	copy := cs.Copy()

	if !Equals(cs, copy) {
		t.Errorf("original (%q) != copy (%q)", cs, copy)
	}

	//case1 -- empty ClauseSet, chagne copy
	cs = ClauseSet{}
	copy = cs.Copy()
	copy.Append(one)

	if Equals(cs, copy) {
		t.Errorf("original (%q) == Copy().Append(%q) (%q)", cs, one, copy)
	}

	//case2 -- 1 thing in ClauseSet, don't change
	cs = ClauseSet{}
	cs.Append(two)
	copy = cs.Copy()

	if !Equals(cs, copy) {
		t.Errorf("original (%q) != copy (%q)", cs, copy)
	}

	//case3 -- 1 thing in ClauseSet, chagne copy
	cs = ClauseSet{}
	cs.Append(two)
	copy = cs.Copy()
	copy.Append(one)

	if Equals(cs, copy) {
		t.Errorf("original (%q) == Copy().Append(%q, %q) (%q)", cs, one, two, copy)
	}

}
func TestAppend(t *testing.T) {
	empty, one, two, _ := clause.ConstructTestClauses()

	//case0 -- 1 clause
	cs := ClauseSet{}
	cs.Append(empty)
	got := cs.String()
	want := "{{}}"
	if got != want {
		t.Errorf("Append(%q) == %q, want %q", empty, got, want)
	}

	//case1 -- 2 things in ClauseSet (added in sorted order)
	cs = ClauseSet{}
	cs.Append(empty)
	cs.Append(one)
	got = cs.String()
	want = "{{}, {A}}"
	if got != want {
		t.Errorf("Append(%q, %q) == %q, want %q", empty, one, got, want)
	}

	//case2 -- 2 things in ClauseSet (added in non-sorted order)
	cs = ClauseSet{}
	cs.Append(one)
	cs.Append(empty)
	got = cs.String()
	want = "{{}, {A}}"
	if got != want {
		t.Errorf("Append(%q, %q) == %q, want %q", one, empty, got, want)
	}

	//case3 -- 3 things in ClauseSet (added in sorted order)
	cs = ClauseSet{}
	cs.Append(empty)
	cs.Append(one)
	cs.Append(two)
	got = cs.String()
	want = "{{}, {A}, {A, B}}"
	if got != want {
		t.Errorf("Append(%q, %q, %q) == %q, want %q", empty, one, two, got, want)
	}

	//case4 -- 3 things in ClauseSet (added in non-sorted order)
	cs = ClauseSet{}
	cs.Append(two)
	cs.Append(empty)
	cs.Append(one)
	got = cs.String()
	want = "{{}, {A}, {A, B}}"
	if got != want {
		t.Errorf("Append(%q, %q, %q) == %q, want %q", two, empty, one, got, want)
	}

	a, _, nb := literal.ConstructTestLiterals()
	nOne := clause.Clause{}
	nOne.Append(a.Negation())

	nTwo := clause.Clause{}
	nTwo.Append(a)
	nTwo.Append(nb)

	//case5 -- 2 things in ClauseSet -- same length, but one less than other (added in sorted order)
	cs = ClauseSet{}
	cs.Append(one)
	cs.Append(nOne)
	got = cs.String()
	want = "{{A}, {~A}}"
	if got != want {
		t.Errorf("Append(%q, %q) == %q, want %q", one, nOne, got, want)
	}

	//case6 -- 2 things in ClauseSet -- same length, but one less than other (added in non-sorted order)
	cs = ClauseSet{}
	cs.Append(nOne)
	cs.Append(one)
	got = cs.String()
	want = "{{A}, {~A}}"
	if got != want {
		t.Errorf("Append(%q, %q) == %q, want %q", nOne, one, got, want)
	}

	//case7 -- 2 things in ClauseSet -- same length, but one less than other (added in sorted order)
	cs = ClauseSet{}
	cs.Append(two)
	cs.Append(nTwo)
	got = cs.String()
	want = "{{A, B}, {A, ~B}}"
	if got != want {
		t.Errorf("Append(%q, %q) == %q, want %q", two, nTwo, got, want)
	}

	//case7 -- 2 things in ClauseSet -- same length, but one less than other (added in non-sorted order)
	cs = ClauseSet{}
	cs.Append(nTwo)
	cs.Append(two)
	got = cs.String()
	want = "{{A, B}, {A, ~B}}"
	if got != want {
		t.Errorf("Append(%q, %q) == %q, want %q", nTwo, two, got, want)
	}

}