예제 #1
0
func BenchmarkBuilder(b *testing.B) {
	b.ReportAllocs()

	for i := 0; i < b.N; i++ {
		b := NewBuilder()
		lit := make([]*Robdd, 10)
		for j := range lit {
			lit[j] = b.NewLiteral(boolean.Var(j))
		}
		d1 := b.Apply(OpXor, lit[0], lit[1])
		d2 := b.Apply(OpOr, lit[2], lit[3])
		d3 := b.Apply(OpAnd, lit[4], lit[5])
		d4 := b.Apply(OpIff, lit[6], lit[7])
		d5 := b.Apply(OpImplies, lit[8], lit[9])

		d1 = b.Apply(OpXor, d1, d3)
		d2 = b.Apply(OpAnd, d2, d5)
		d3 = b.Apply(OpOr, d1, d4)
		d4 = b.Apply(OpImplies, d2, d3)
		d5 = b.Apply(OpIff, b.NewLiteral(boolean.Var(10)), d4)
	}
}
예제 #2
0
func TestSAT(t *testing.T) {
	b := NewBuilder()
	unsat := b.Constant(false)

	check := func() {
		if assign := unsat.AnySat(); assign != nil {
			t.Errorf("AnySat returned %v for unsatisfiable formula",
				assign)
		}
		if n := unsat.Size(); n != 1 {
			t.Errorf("unsatisfiable formula has %d nodes, expected one", n)
		}
	}
	check()

	unsat = b.Apply(OpAnd, unsat, b.Constant(true))
	unsat = b.Apply(OpAnd, unsat, b.NewLiteral(boolean.Var(1)))
	unsat = b.Apply(OpAnd, unsat, unsat)
}
예제 #3
0
func TestBDD(t *testing.T) {
	b := NewBuilder()

	// Construct the formula (0 and 1) or (2 and (1 or 0)).
	var v []*Robdd
	for i := 0; i < 4; i++ {
		v = append(v, b.NewLiteral(boolean.Var(i)))
	}
	f := b.Apply(OpAnd, v[0], v[1])
	g := b.Apply(OpAnd, v[2], b.Apply(OpOr, v[1], v[0]))
	h := b.Apply(OpOr, f, g)
	_ = h

	for _, c := range []struct {
		bdd    *Robdd
		assign map[boolean.Var]bool
	}{
		{f, map[boolean.Var]bool{0: false, 1: false}},
		{g, map[boolean.Var]bool{0: true, 1: true, 2: false}},
		{h, map[boolean.Var]bool{0: false, 1: false, 2: true}},
	} {
		if checkSat(c.bdd.root, c.assign) {
			t.Error("construction error")
		}
	}

	for _, bdd := range []*Robdd{f, g, h} {
		if assign := bdd.AnySat(); !checkSat(bdd.root, assign) {
			t.Errorf("not a SAT solution: %v", assign)
		}
	}

	r := h.Eval(func(v boolean.Var) bool {
		return [...]bool{true, false, true}[int(v)]
	})
	if !r {
		t.Error("expected true, got false from Eval")
	}
}