mirror of
https://github.com/mudler/luet.git
synced 2025-09-09 19:19:49 +00:00
update vendor
This commit is contained in:
104
vendor/github.com/crillab/gophersat/explain/parser.go
generated
vendored
Normal file
104
vendor/github.com/crillab/gophersat/explain/parser.go
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
package explain
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// parseClause parses a line representing a clause in the DIMACS CNF syntax.
|
||||
func parseClause(fields []string) ([]int, error) {
|
||||
clause := make([]int, 0, len(fields)-1)
|
||||
for _, rawLit := range fields {
|
||||
lit, err := strconv.Atoi(rawLit)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not parse clause %v: %v", fields, err)
|
||||
}
|
||||
if lit != 0 {
|
||||
clause = append(clause, lit)
|
||||
}
|
||||
}
|
||||
return clause, nil
|
||||
}
|
||||
|
||||
// ParseCNF parses a CNF and returns the associated problem.
|
||||
func ParseCNF(r io.Reader) (*Problem, error) {
|
||||
sc := bufio.NewScanner(r)
|
||||
var pb Problem
|
||||
for sc.Scan() {
|
||||
line := sc.Text()
|
||||
fields := strings.Fields(line)
|
||||
if len(fields) == 0 {
|
||||
continue
|
||||
}
|
||||
switch fields[0] {
|
||||
case "c":
|
||||
continue
|
||||
case "p":
|
||||
if err := pb.parseHeader(fields); err != nil {
|
||||
return nil, fmt.Errorf("could not parse header %q: %v", line, err)
|
||||
}
|
||||
default:
|
||||
if err := pb.parseClause(fields); err != nil {
|
||||
return nil, fmt.Errorf("could not parse clause %q: %v", line, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := sc.Err(); err != nil {
|
||||
return nil, fmt.Errorf("could not parse problem: %v", err)
|
||||
}
|
||||
return &pb, nil
|
||||
}
|
||||
|
||||
func (pb *Problem) parseHeader(fields []string) error {
|
||||
if len(fields) != 4 {
|
||||
return fmt.Errorf("expected 4 fields, got %d", len(fields))
|
||||
}
|
||||
strVars := fields[2]
|
||||
strClauses := fields[3]
|
||||
var err error
|
||||
pb.NbVars, err = strconv.Atoi(fields[2])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid number of vars %q: %v", strVars, err)
|
||||
}
|
||||
if pb.NbVars < 0 {
|
||||
return fmt.Errorf("negative number of vars %d", pb.NbVars)
|
||||
}
|
||||
pb.units = make([]int, pb.NbVars)
|
||||
pb.NbClauses, err = strconv.Atoi(fields[3])
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid number of clauses %s: %v", strClauses, err)
|
||||
}
|
||||
if pb.NbClauses < 0 {
|
||||
return fmt.Errorf("negative number of clauses %d", pb.NbClauses)
|
||||
}
|
||||
pb.Clauses = make([][]int, 0, pb.NbClauses)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (pb *Problem) parseClause(fields []string) error {
|
||||
clause, err := parseClause(fields)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
pb.Clauses = append(pb.Clauses, clause)
|
||||
if len(clause) == 1 {
|
||||
lit := clause[0]
|
||||
v := lit
|
||||
if lit < 0 {
|
||||
v = -v
|
||||
}
|
||||
if v > pb.NbVars {
|
||||
// There was an error in the header
|
||||
return fmt.Errorf("found lit %d but problem was supposed to hold only %d vars", lit, pb.NbVars)
|
||||
}
|
||||
if lit > 0 {
|
||||
pb.units[v-1] = 1
|
||||
} else {
|
||||
pb.units[v-1] = -1
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
Reference in New Issue
Block a user