mirror of
https://github.com/mudler/luet.git
synced 2025-07-17 08:52:14 +00:00
184 lines
4.7 KiB
Go
184 lines
4.7 KiB
Go
package solver
|
|
|
|
//
|
|
// import "log"
|
|
//
|
|
// // Subsumes returns true iff c subsumes c2.
|
|
// func (c *Clause) Subsumes(c2 *Clause) bool {
|
|
// if c.Len() > c2.Len() {
|
|
// return false
|
|
// }
|
|
// for _, lit := range c.lits {
|
|
// found := false
|
|
// for _, lit2 := range c2.lits {
|
|
// if lit == lit2 {
|
|
// found = true
|
|
// break
|
|
// }
|
|
// if lit2 > lit {
|
|
// return false
|
|
// }
|
|
// }
|
|
// if !found {
|
|
// return false
|
|
// }
|
|
// }
|
|
// return true
|
|
// }
|
|
//
|
|
// // SelfSubsumes returns true iff c self-subsumes c2.
|
|
// func (c *Clause) SelfSubsumes(c2 *Clause) bool {
|
|
// oneNeg := false
|
|
// for _, lit := range c.lits {
|
|
// found := false
|
|
// for _, lit2 := range c2.lits {
|
|
// if lit == lit2 {
|
|
// found = true
|
|
// break
|
|
// }
|
|
// if lit == lit2.Negation() {
|
|
// if oneNeg { // We want exactly one, but this is the second
|
|
// return false
|
|
// }
|
|
// oneNeg = true
|
|
// found = true
|
|
// break
|
|
// }
|
|
// if lit2 > lit { // We won't find it anymore
|
|
// return false
|
|
// }
|
|
// }
|
|
// if !found {
|
|
// return false
|
|
// }
|
|
// }
|
|
// return oneNeg
|
|
// }
|
|
//
|
|
// // Simplify simplifies the given clause by removing redundant lits.
|
|
// // If the clause is trivially satisfied (i.e contains both a lit and its negation),
|
|
// // true is returned. Otherwise, false is returned.
|
|
// func (c *Clause) Simplify() (isSat bool) {
|
|
// c.Sort()
|
|
// lits := make([]Lit, 0, len(c.lits))
|
|
// i := 0
|
|
// for i < len(c.lits) {
|
|
// if i < len(c.lits)-1 && c.lits[i] == c.lits[i+1].Negation() {
|
|
// return true
|
|
// }
|
|
// lit := c.lits[i]
|
|
// lits = append(lits, lit)
|
|
// i++
|
|
// for i < len(c.lits) && c.lits[i] == lit {
|
|
// i++
|
|
// }
|
|
// }
|
|
// if len(lits) < len(c.lits) {
|
|
// c.lits = lits
|
|
// }
|
|
// return false
|
|
// }
|
|
//
|
|
// // Generate returns a subsumed clause from c and c2, by removing v.
|
|
// func (c *Clause) Generate(c2 *Clause, v Var) *Clause {
|
|
// c3 := &Clause{lits: make([]Lit, 0, len(c.lits)+len(c2.lits)-2)}
|
|
// for _, lit := range c.lits {
|
|
// if lit.Var() != v {
|
|
// c3.lits = append(c3.lits, lit)
|
|
// }
|
|
// }
|
|
// for _, lit2 := range c2.lits {
|
|
// if lit2.Var() != v {
|
|
// c3.lits = append(c3.lits, lit2)
|
|
// }
|
|
// }
|
|
// return c3
|
|
// }
|
|
//
|
|
// func (pb *Problem) preprocess() {
|
|
// log.Printf("Preprocessing... %d clauses currently", len(pb.Clauses))
|
|
// occurs := make([][]int, pb.NbVars*2)
|
|
// for i, c := range pb.Clauses {
|
|
// for j := 0; j < c.Len(); j++ {
|
|
// occurs[c.Get(j)] = append(occurs[c.Get(j)], i)
|
|
// }
|
|
// }
|
|
// modified := true
|
|
// neverModified := true
|
|
// for modified {
|
|
// modified = false
|
|
// for i := 0; i < pb.NbVars; i++ {
|
|
// if pb.Model[i] != 0 {
|
|
// continue
|
|
// }
|
|
// v := Var(i)
|
|
// lit := v.Lit()
|
|
// nbLit := len(occurs[lit])
|
|
// nbLit2 := len(occurs[lit.Negation()])
|
|
// if (nbLit < 10 || nbLit2 < 10) && (nbLit != 0 || nbLit2 != 0) {
|
|
// modified = true
|
|
// neverModified = false
|
|
// // pb.deleted[v] = true
|
|
// log.Printf("%d can be removed: %d and %d", lit.Int(), len(occurs[lit]), len(occurs[lit.Negation()]))
|
|
// for _, idx1 := range occurs[lit] {
|
|
// for _, idx2 := range occurs[lit.Negation()] {
|
|
// c1 := pb.Clauses[idx1]
|
|
// c2 := pb.Clauses[idx2]
|
|
// newC := c1.Generate(c2, v)
|
|
// if !newC.Simplify() {
|
|
// switch newC.Len() {
|
|
// case 0:
|
|
// log.Printf("Inferred UNSAT")
|
|
// pb.Status = Unsat
|
|
// return
|
|
// case 1:
|
|
// log.Printf("Unit %d", newC.First().Int())
|
|
// lit2 := newC.First()
|
|
// if lit2.IsPositive() {
|
|
// if pb.Model[lit2.Var()] == -1 {
|
|
// pb.Status = Unsat
|
|
// return
|
|
// }
|
|
// pb.Model[lit2.Var()] = 1
|
|
// } else {
|
|
// if pb.Model[lit2.Var()] == 1 {
|
|
// pb.Status = Unsat
|
|
// return
|
|
// }
|
|
// pb.Model[lit2.Var()] = -1
|
|
// }
|
|
// pb.Units = append(pb.Units, lit2)
|
|
// default:
|
|
// pb.Clauses = append(pb.Clauses, newC)
|
|
// }
|
|
// }
|
|
// }
|
|
// }
|
|
// nbRemoved := 0
|
|
// for _, idx := range occurs[lit] {
|
|
// pb.Clauses[idx] = pb.Clauses[len(pb.Clauses)-nbRemoved-1]
|
|
// nbRemoved++
|
|
// }
|
|
// for _, idx := range occurs[lit.Negation()] {
|
|
// pb.Clauses[idx] = pb.Clauses[len(pb.Clauses)-nbRemoved-1]
|
|
// nbRemoved++
|
|
// }
|
|
// pb.Clauses = pb.Clauses[:len(pb.Clauses)-nbRemoved]
|
|
// log.Printf("clauses=%s", pb.CNF())
|
|
// // Redo occurs
|
|
// occurs = make([][]int, pb.NbVars*2)
|
|
// for i, c := range pb.Clauses {
|
|
// for j := 0; j < c.Len(); j++ {
|
|
// occurs[c.Get(j)] = append(occurs[c.Get(j)], i)
|
|
// }
|
|
// }
|
|
// continue
|
|
// }
|
|
// }
|
|
// }
|
|
// if !neverModified {
|
|
// pb.simplify()
|
|
// }
|
|
// log.Printf("Done. %d clauses now", len(pb.Clauses))
|
|
// }
|