/* A -> (N v Q) ~(N v ~A) A -> Q (conclusion) */ func SatValid(t *testing.T) { a := literal.Literal{"A", false} na := a.Negation() n := literal.Literal{"N", false} nn := n.Negation() q := literal.Literal{"Q", false} nq := q.Negation() one := clause.Clause{} one.Append(a) two := clause.Clause{} two.Append(nq) three := clause.Clause{} three.Append(nn) four := clause.Clause{} four.Append(na) four.Append(n) four.Append(q) CS := clauseset.ClauseSet{} CS.Append(one) CS.Append(two) CS.Append(three) CS.Append(four) sat, _ := Satisfiable(CS) if sat { t.Errorf("ClauseSet %q was Satisfiable, so it is an invalid argument (it should be valid)", CS) } }
/* A -> B ~A ~B (conclusion) */ func SatInvalid(t *testing.T) { na := literal.Literal{"A", true} b := literal.Literal{"B", false} one := clause.Clause{} one.Append(na) two := clause.Clause{} two.Append(b) three := clause.Clause{} three.Append(na) three.Append(b) CS := clauseset.ClauseSet{} CS.Append(one) CS.Append(two) CS.Append(three) CS.Indent = 0 sat, _ := Satisfiable(CS) if !sat { t.Errorf("ClauseSet %q was not Satisfiable, so it is a valid argument (it should be invalid)", CS) } }
//ConstructClause takes a connector and returns a Clause //assumes the connector is in CNF form func ConstructClause(conn connector.Connector) clause.Clause { newClause := clause.Clause{} if conn.Type == "Literal" || conn.Type == "Neg" { newLiteral := ConstructLiteral(conn) newClause.Append(newLiteral) } else { for _, child := range conn.Children { newLiteral := ConstructLiteral(child) newClause.Append(newLiteral) } } return newClause }
func TestAppend(t *testing.T) { empty, one, two, _ := clause.ConstructTestClauses() //case0 -- 1 clause cs := ClauseSet{} cs.Append(empty) got := cs.String() want := "{{}}" if got != want { t.Errorf("Append(%q) == %q, want %q", empty, got, want) } //case1 -- 2 things in ClauseSet (added in sorted order) cs = ClauseSet{} cs.Append(empty) cs.Append(one) got = cs.String() want = "{{}, {A}}" if got != want { t.Errorf("Append(%q, %q) == %q, want %q", empty, one, got, want) } //case2 -- 2 things in ClauseSet (added in non-sorted order) cs = ClauseSet{} cs.Append(one) cs.Append(empty) got = cs.String() want = "{{}, {A}}" if got != want { t.Errorf("Append(%q, %q) == %q, want %q", one, empty, got, want) } //case3 -- 3 things in ClauseSet (added in sorted order) cs = ClauseSet{} cs.Append(empty) cs.Append(one) cs.Append(two) got = cs.String() want = "{{}, {A}, {A, B}}" if got != want { t.Errorf("Append(%q, %q, %q) == %q, want %q", empty, one, two, got, want) } //case4 -- 3 things in ClauseSet (added in non-sorted order) cs = ClauseSet{} cs.Append(two) cs.Append(empty) cs.Append(one) got = cs.String() want = "{{}, {A}, {A, B}}" if got != want { t.Errorf("Append(%q, %q, %q) == %q, want %q", two, empty, one, got, want) } a, _, nb := literal.ConstructTestLiterals() nOne := clause.Clause{} nOne.Append(a.Negation()) nTwo := clause.Clause{} nTwo.Append(a) nTwo.Append(nb) //case5 -- 2 things in ClauseSet -- same length, but one less than other (added in sorted order) cs = ClauseSet{} cs.Append(one) cs.Append(nOne) got = cs.String() want = "{{A}, {~A}}" if got != want { t.Errorf("Append(%q, %q) == %q, want %q", one, nOne, got, want) } //case6 -- 2 things in ClauseSet -- same length, but one less than other (added in non-sorted order) cs = ClauseSet{} cs.Append(nOne) cs.Append(one) got = cs.String() want = "{{A}, {~A}}" if got != want { t.Errorf("Append(%q, %q) == %q, want %q", nOne, one, got, want) } //case7 -- 2 things in ClauseSet -- same length, but one less than other (added in sorted order) cs = ClauseSet{} cs.Append(two) cs.Append(nTwo) got = cs.String() want = "{{A, B}, {A, ~B}}" if got != want { t.Errorf("Append(%q, %q) == %q, want %q", two, nTwo, got, want) } //case7 -- 2 things in ClauseSet -- same length, but one less than other (added in non-sorted order) cs = ClauseSet{} cs.Append(nTwo) cs.Append(two) got = cs.String() want = "{{A, B}, {A, ~B}}" if got != want { t.Errorf("Append(%q, %q) == %q, want %q", nTwo, two, got, want) } }
func ToCNF(statement string) clauseset.ClauseSet { rows := getRows(getLiterals(statement)) new_clauseset := clauseset.ClauseSet{} for _, row := range rows { sort.Sort(ByLength(row)) statement_cpy := statement[:1] + statement[1:] for _, l := range row { // @ == TRUE "!" == FALSE replacement_string := "N/A" if len(l) == 1 { replacement_string = "@" } else { replacement_string = "!" l = l[2:3] } // do the straight replacement r := regexp.MustCompile(fmt.Sprintf("%s", l)) statement_cpy = r.ReplaceAllString(statement_cpy, replacement_string) } for statement_cpy != "TRUE" && statement_cpy != "FALSE" { r := regexp.MustCompile("(~@|~\\(@\\))") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("(~!|~\\(!\\))") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("\\(@\\)") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("\\(!\\)") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("@") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("!") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("\\(TRUE\\)") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("\\(FALSE\\)") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("(~TRUE|~\\(TRUE\\))") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("(~FALSE|~\\(FALSE\\))") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("TRUEv(TRUE|FALSE)") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("(TRUE|FALSE)vTRUE") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("FALSEvFALSE") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("TRUE\\^TRUE") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("(TRUE|FALSE)\\^FALSE") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("FALSE\\^(TRUE|FALSE)") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("FALSE->(TRUE|FALSE)") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("TRUE\\->FALSE") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("TRUE\\->TRUE") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("TRUE<\\->TRUE") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("FALSE<\\->FALSE") statement_cpy = r.ReplaceAllString(statement_cpy, "TRUE") r = regexp.MustCompile("TRUE<\\->FALSE") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") r = regexp.MustCompile("FALSE<\\->TRUE") statement_cpy = r.ReplaceAllString(statement_cpy, "FALSE") } if statement_cpy == "FALSE" { new_clause := clause.Clause{} for _, l := range row { if len(l) == 1 { lit := literal.Literal{Name: l, Negated: true} new_clause.Append(lit) } else { lit := literal.Literal{Name: l[2:3], Negated: false} new_clause.Append(lit) } } new_clauseset.Append(new_clause) } } return new_clauseset }