Skip to content
Snippets Groups Projects
Commit ebe864d4 authored by Régis Blanc's avatar Régis Blanc
Browse files

some properties

parent 9ac401bd
Branches
Tags
No related merge requests found
...@@ -8,7 +8,7 @@ object SatFun { ...@@ -8,7 +8,7 @@ object SatFun {
case class Not(f: Formula) extends Formula case class Not(f: Formula) extends Formula
case class Var(i: Int) extends Formula case class Var(i: Int) extends Formula
//vars are numbered from 1 to n, and Not(Var(n)) is represented as -n //vars are numbered from 2 to n+1, and Not(Var(n)) is represented as -n. 1 is true and -1 is false
sealed abstract class VarList sealed abstract class VarList
case class VarCons(head: Int, tail: VarList) extends VarList case class VarCons(head: Int, tail: VarList) extends VarList
case class VarNil() extends VarList case class VarNil() extends VarList
...@@ -47,44 +47,40 @@ object SatFun { ...@@ -47,44 +47,40 @@ object SatFun {
case VarLit(b) => b case VarLit(b) => b
} }
def vars(formula: Formula): Set[Int] = formula match {
case Var(n) => Set(n)
case Not(f) => vars(f)
case And(f1, f2) => vars(f1) ++ vars(f2)
case Or(f1, f2) => vars(f1) ++ vars(f2)
}
def concatClauses(cll1: ClauseList, cll2: ClauseList): ClauseList = cll1 match { def concatClauses(cll1: ClauseList, cll2: ClauseList): ClauseList = cll1 match {
case ClauseCons(cl, tail) => ClauseCons(cl, concatClauses(tail, cll2)) case ClauseCons(cl, tail) => ClauseCons(cl, concatClauses(tail, cll2))
case ClauseNil() => cll2 case ClauseNil() => cll2
case cl@ClauseLit(_) => ClauseCons(cl, clls) case ClauseLit(b) => ClauseCons(VarLit(b), cll2)
} }
def concatVars(l1: VarList, l2: VarList): VarList = l1 match { def concatVars(l1: VarList, l2: VarList): VarList = l1 match {
case VarCons(v, vs) => VarCons(v, concatVars(vs, l2)) case VarCons(v, vs) => VarCons(v, concatVars(vs, l2))
case VarNil() => l2 case VarNil() => l2
case v@VarLit(_) => VarCons(v, vs) case VarLit(b) => if(b) VarCons(1, l2) else VarCons(-1, l2)
} }
def distributeClause(cl: VarList, cll: ClauseList): ClauseList = cll match { def distributeClause(cl: VarList, cll: ClauseList): ClauseList = cll match {
case ClauseCons(cl2, cl2s) => ClauseCons(concatVars(cl, cl2), distributeClause(cl, cl2s)) case ClauseCons(cl2, cl2s) => ClauseCons(concatVars(cl, cl2), distributeClause(cl, cl2s))
case ClauseNil() => ClauseNil() case ClauseNil() => ClauseNil()
case cl@ClauseLit(b) => ClauseCons(cl, clls) case ClauseLit(b) => if(b) ClauseCons(VarCons(1, cl), ClauseNil()) else ClauseCons(VarCons(-1, cl), ClauseNil())
} }
def distribute(cll1: ClauseList, cll2: ClauseList): ClauseList = cll1 match { def distribute(cll1: ClauseList, cll2: ClauseList): ClauseList = cll1 match {
case ClauseCons(cl, cls) => concatClauses(distributeClause(cl, cll2), distribute(cls, cll2)) case ClauseCons(cl, cls) => concatClauses(distributeClause(cl, cll2), distribute(cls, cll2))
case ClauseNil() => cll2 case ClauseNil() => cll2
case ClauseLit(b) => distributeClause(VarLit(b), cll2)
} }
def negateClauses(cll: ClauseList): ClauseList = cll match { def negateClauses(cll: ClauseList): ClauseList = cll match {
case ClauseCons(cl, cls) => ClauseCons(negateVars(cl), negateClauses(cls)) case ClauseCons(cl, cls) => ClauseCons(negateVars(cl), negateClauses(cls))
case ClauseNil() => ClauseNil() case ClauseNil() => ClauseNil()
case ClauseLit(b) => ClauseLit(!b)
} }
def negateVars(lst: VarList): VarList = lst match { def negateVars(lst: VarList): VarList = lst match {
case VarCons(v, vs) => VarCons(-v, negateVars(vs)) case VarCons(v, vs) => VarCons(-v, negateVars(vs))
case VarNil() => VarNil() case VarNil() => VarNil()
case VarLit(b) => VarLit(!b)
} }
def cnfNaive(formula: Formula): ClauseList = formula match { def cnfNaive(formula: Formula): ClauseList = formula match {
...@@ -104,7 +100,6 @@ object SatFun { ...@@ -104,7 +100,6 @@ object SatFun {
case Not(Var(n)) => ClauseCons(VarCons(-n, VarNil()), ClauseNil()) case Not(Var(n)) => ClauseCons(VarCons(-n, VarNil()), ClauseNil())
case Var(n) => ClauseCons(VarCons(n, VarNil()), ClauseNil()) case Var(n) => ClauseCons(VarCons(n, VarNil()), ClauseNil())
} }
def dnfNaive(formula: Formula): ClauseList = formula match { def dnfNaive(formula: Formula): ClauseList = formula match {
case And(f1, f2) => { case And(f1, f2) => {
val dnf1 = dnfNaive(f1) val dnf1 = dnfNaive(f1)
...@@ -122,47 +117,80 @@ object SatFun { ...@@ -122,47 +117,80 @@ object SatFun {
case Not(Var(n)) => ClauseCons(VarCons(-n, VarNil()), ClauseNil()) case Not(Var(n)) => ClauseCons(VarCons(-n, VarNil()), ClauseNil())
case Var(n) => ClauseCons(VarCons(n, VarNil()), ClauseNil()) case Var(n) => ClauseCons(VarCons(n, VarNil()), ClauseNil())
} }
def property1(formula: Formula, assignment: Map[Int, Boolean]): Boolean = {
val dnfFormula = dnfNaive(formula)
eval(formula, assignment) == evalDnf(dnfFormula, assignment)
} ensuring(_ == true)
def vars(formula: Formula): Set[Int] = formula match {
case Var(n) => Set(n)
case Not(f) => vars(f)
case And(f1, f2) => vars(f1) ++ vars(f2)
case Or(f1, f2) => vars(f1) ++ vars(f2)
}
def isContradictory(clause: VarList, vars: Set[Int]): Boolean = clause match { def isContradictory(clause: VarList, vars: Set[Int]): Boolean = clause match {
case VarCons(v, vs) => vars.contains(-v) || isContradictory(vs, vars ++ Set(v)) case VarCons(v, vs) => vars.contains(-v) || vars.contains(-1) || isContradictory(vs, vars ++ Set(v))
case VarNil() => false case VarNil() => false
case VarLit(b) => !b
} }
def isSatDnf(clauses: ClauseList): Boolean = clauses match { def isSatDnf(clauses: ClauseList): Boolean = clauses match {
case ClauseCons(cl, cls) => !isContradictory(cl, Set.empty) || isSatDnf(cls) case ClauseCons(cl, cls) => !isContradictory(cl, Set.empty) || isSatDnf(cls)
case ClauseNil() => false case ClauseNil() => false
case ClauseLit(b) => b
} }
//for substitute we assume we are dealing with a cnf formula
def substitute(formula: ClauseList, variable: Int, value: Boolean): ClauseList = formula match { def substitute(formula: ClauseList, variable: Int, value: Boolean): ClauseList = formula match {
case ClauseNil() => ClauseNil() case ClauseNil() => ClauseNil()
case ClauseCons(cl, cls) => case ClauseCons(cl, cls) => ClauseCons(substitute(cl, variable, value), substitute(cls, variable, value))
case ClauseLit(b) => ClauseLit(b)
} }
def substitute(vars: VarList, variable: Int, value: Boolean): VarList = vars match { def substitute(vars: VarList, variable: Int, value: Boolean): VarList = vars match {
case VarNil() => VarNil() case VarNil() => VarNil()
case VarCons(v, vs) => if(v == variable) case VarLit(b) => VarLit(b)
} case VarCons(v, vs) =>
if (v == variable && value) VarLit(true)
def choose(formula: ClauseList): Int = { else if(v == variable && !value) substitute(vs, variable, value)
formula.head.head else if(v == -variable && value) substitute(vs, variable, value)
else if(v == -variable && !value) VarLit(true)
else VarCons(v, substitute(vs, variable, value))
}
def choose(formula: ClauseList): Int = formula match {
case ClauseCons(varList, cls) => varList match {
case VarCons(head, vs) => head
case VarNil() => 0
case VarLit(b) => 0
}
case ClauseNil() => 0
case ClauseLit(b) => 0
} }
def dpll(formula: ClauseList): Boolean = { def dpll(formula: ClauseList): Boolean = formula match {
case ClauseNil() => true
case ClauseLit(b) => b
case _ => {
val chosenVar = choose(formula)
val lhs = dpll(substitute(formula, chosenVar, true))
val rhs = dpll(substitute(formula, chosenVar, false))
lhs || rhs
}
} }
def main(args: Array[String]) {
val f1 = And(Var(1), Or(Var(1), Not(Var(2)), Var(3)), Var(2), Not(Var(3)))
val dnff1 = clauses2list(dnfNaive(f1))
val vars1 = vars(f1)
vars.foreach(v => {
}) // def main(args: Array[String]) {
println(f1 + " translated in dnf as:\n\t" + dnff1.mkString("\n\t")) // val f1 = And(Var(1), Or(Var(1), Not(Var(2)), Var(3)), Var(2), Not(Var(3)))
} // val dnff1 = clauses2list(dnfNaive(f1))
// val vars1 = vars(f1)
// vars.foreach(v => {
//
//
// })
// println(f1 + " translated in dnf as:\n\t" + dnff1.mkString("\n\t"))
// }
//some non-leon functions to test the program with scala //some non-leon functions to test the program with scala
object False { object False {
...@@ -188,9 +216,11 @@ object SatFun { ...@@ -188,9 +216,11 @@ object SatFun {
def clause2list(cl: VarList): List[Int] = cl match { def clause2list(cl: VarList): List[Int] = cl match {
case VarCons(v, vs) => v :: clause2list(vs) case VarCons(v, vs) => v :: clause2list(vs)
case VarNil() => Nil case VarNil() => Nil
case VarLit(b) => if(b) List(1) else List(-1)
} }
def clauses2list(cll: ClauseList): List[List[Int]] = cll match { def clauses2list(cll: ClauseList): List[List[Int]] = cll match {
case ClauseCons(cl, cls) => clause2list(cl) :: clauses2list(cls) case ClauseCons(cl, cls) => clause2list(cl) :: clauses2list(cls)
case ClauseNil() => Nil case ClauseNil() => Nil
case ClauseLit(b) => if(b) List(List(1)) else List(List(-1))
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment