Пример #1
0
/*
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)
	}

}
Пример #2
0
/*
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)
	}
}
Пример #3
0
//FindValidity finds the validity of the argument (given as a ClauseSet)
func FindValidity(CS clauseset.ClauseSet, filename string) {
	fmt.Printf("Starting ClauseSet: %s\n", CS)

	CS.Indent = 0
	sat, tree := Satisfiable(CS)
	treeJson, _ := json.Marshal(tree)

	f, _ := os.Create(filename)
	f.WriteString(string(treeJson))

	fmt.Print("Conclusion: ")
	if sat {
		fmt.Printf("Satisfiable(%s) == %t; INVALID\n", CS, sat)
	} else {
		fmt.Printf("Satisfiable(%s) == %t; VALID\n", CS, sat)
	}
}
Пример #4
0
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
}
Пример #5
0
//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
}