func ordered(db *db.DB, a *assignment.Assignment) (l *cnf.Lit) { // find the first in-order unassigned literal for i := uint(1); i <= a.Len(); i++ { if p, _ := a.Get(i); p == guess.Unassigned { return &cnf.Lit{i, cnf.Pos} } } return &cnf.Lit{0, 0} }
func (lc *LitCounts) GetNextVmtf(a *assignment.Assignment) (l *cnf.Lit) { var lit uint for i := range lc.vmtf { if lc.vmtf[i].lit < 0 { lit = uint(-1 * lc.vmtf[i].lit) } else { lit = uint(lc.vmtf[i].lit) } if val, err := a.Get(lit); val == guess.Unassigned && err == nil { if lc.vmtf[i].lit < 0 { return &cnf.Lit{uint(lc.vmtf[i].lit * -1), cnf.Pos} } else { return &cnf.Lit{uint(lc.vmtf[i].lit), cnf.Pos} } } } panic("getNextVmtf is broken") }
// We'll use a modified MOMS rule that only looks at binary clauses func moms(db *db.DB, a *assignment.Assignment) (l *cnf.Lit) { var ( counts = make([]int, a.Guess().Len()) eCount int vals [2]uint g = a.Guess() biggest = 0 biggestI = -1 ) // Count up the total lits in binary clauses for e := db.Learned; e != nil; e = e.Next { eCount = 0 for _, l := range e.Clause.Lits { if v, _ := g.Get(l.Val); v == guess.Unassigned { eCount++ if eCount > 2 { break } vals[eCount-1] = l.Val } } if eCount <= 2 { for i := 0; i < eCount; i++ { counts[vals[i]-1]++ } } } // Search for the biggest for i, v := range counts { if v > biggest { biggest = v biggestI = i } } if biggestI == -1 { return random(db, a) } else { return &cnf.Lit{uint(biggestI + 1), byte((rand.Int() % 2) + 1)} } panic("MOMS is broken") }
func random(db *db.DB, a *assignment.Assignment) (l *cnf.Lit) { sign := byte((rand.Int() % 2) + 1) val := uint((rand.Int() % int(a.Len())) + 1) for i := val; i <= a.Len(); i++ { if v, _ := a.Get(i); v == guess.Unassigned { return &cnf.Lit{i, sign} } } for i := uint(1); i < val; i++ { if v, _ := a.Get(i); v == guess.Unassigned { return &cnf.Lit{i, sign} } } return &cnf.Lit{0, 0} }
func DpllTimeout(cdb *db.DB, a *assignment.Assignment, b *Brancher, m *db.Manager, adapt *Adapter, timeout <-chan time.Time) *guess.Guess { nVar := a.Guess().Len() aStack := make([]dpllStackNode, nVar) top := -1 for { top++ aStack[top].l = b.Decide(cdb, a) aStack[top].Flipped = false a.PushAssign(aStack[top].l.Val, aStack[top].l.Pol) for { select { case <-timeout: return nil default: } status := cdb.Bcp(a.Guess(), *aStack[top].l, m) if status == db.Conflict { // BackTrack for aStack[top].Flipped == true { top-- a.PopAssign() } if top < 0 { return nil } // Flip the assignment a.PopAssign() aStack[top].l.Flip() aStack[top].Flipped = true a.PushAssign(aStack[top].l.Val, aStack[top].l.Pol) // Reconfigure if neccessary if adapt != nil { adapt.Reconfigure(cdb, b, m) } } else if status == db.Sat { return a.Guess() } else { break } } } panic("Dpll is broken") }
func vsids(db *db.DB, a *assignment.Assignment) (l *cnf.Lit) { l = db.Counts.Max(a.Guess()) return }