func (c clauseSlice) Less(i, j int) bool { //if they aren't the same length, put the shorter one first if clause.Len(c[i]) != clause.Len(c[j]) { return clause.Len(c[i]) < clause.Len(c[j]) } //they must both be the same size now... for x := 0; x < clause.Len(c[i]); x++ { //literal x is not the same if c[i].Clause[x] != c[j].Clause[x] { //return the lesser one return literal.Less(c[i].Clause[x], c[j].Clause[x]) } } return false }
//Satisfiable implements above function func Satisfiable(CS clauseset.ClauseSet) (bool, Tree) { tree := Tree{Name: CS.String(), Split: ""} fmt.Printf("\n%sSatisfiable(%s)\n", strings.Repeat(" ", CS.Indent), CS) CS.Indent += 2 //if CS = {} : return true if CS.Len() == 0 { fmt.Printf("%sEmpty ClauseSet, returning true\n", strings.Repeat(" ", CS.Indent)) openTree := Tree{Name: "O", Split: ""} tree.Children = append(tree.Children, openTree) return true, tree } //if {} in CS : return false firstElement, err := CS.FirstElement() if err != nil { log.Fatal(err) } if clause.Len(firstElement) == 0 { fmt.Printf("%s{} found in ClauseSet, returning false\n", strings.Repeat(" ", CS.Indent)) closedTree := Tree{Name: "X", Split: ""} tree.Children = append(tree.Children, closedTree) return false, tree } //select L in lit(CS): return Satisfiable(CS_L) || Satisfiable(CS_L') nextLiteral, err2 := CS.NextLiteral() if err2 != nil { log.Fatal(err2) } fmt.Printf("%sSpliting on %s\n", strings.Repeat(" ", CS.Indent), nextLiteral) CSL := CS.Reduce(nextLiteral) CSL.Indent = CS.Indent CSR := CS.Reduce(nextLiteral.Negation()) CSR.Indent = CS.Indent left, tree_l := Satisfiable(CSL) right, tree_r := Satisfiable(CSR) tree_l.Split = nextLiteral.String() tree_r.Split = nextLiteral.Negation().String() tree.Children = append(tree.Children, tree_l) tree.Children = append(tree.Children, tree_r) return left || right, tree }