fork(4) download
  1. import scala.util.parsing.combinator._
  2.  
  3. case class Const(value: Boolean) extends Expr
  4. case class Atom(name: String) extends Expr
  5. case class Not(expr: Expr) extends Expr
  6. case class And(left: Expr, right: Expr) extends Expr
  7. case class Or(left: Expr, right: Expr) extends Expr
  8. case class Iff(left: Expr, right: Expr) extends Expr
  9. case class Imp(left: Expr, right: Expr) extends Expr
  10.  
  11. class MyParser extends JavaTokenParsers {
  12.  
  13. def expr = chainl1(term, parseIffImp) ; def parseIffImp = "<=>" ^^^ {Iff} | "=>" ^^^ {Imp}
  14. def term = chainl1(factor, parseAndOr) ; def parseAndOr = "/\\" ^^^ {And} | "\\/" ^^^ {Or}
  15. def factor: Parser[Expr] = "~" ~> factor ^^ {Not} | primary
  16. def primary = "#T" ^^^ {Const(true)} | "#F" ^^^ {Const(false)} | ident ^^ {Atom} | "(" ~> expr <~ ")"
  17. }
  18.  
  19. object Main extends MyParser {
  20.  
  21. def toStr(expr: Expr, p: Int, r: Int): String = {
  22.  
  23. def par(p0: Int, s: String) = if (p > p0 || (p == p0 && r == 1)) s else ""
  24.  
  25. expr match {
  26. case Const(true) => "#true" case Const(false) => "#false"
  27. case Atom(name) => name case Not(e) => "~" + toStr(e,3,r)
  28. case And(e1, e2) => par(2,"(") + toStr(e1,2,0) + "/\\" + toStr(e2,2,1) + par(2,")")
  29. case Or(e1, e2) => par(2,"(") + toStr(e1,2,0) + "\\/" + toStr(e2,2,1) + par(2,")")
  30. case Imp(e1, e2) => par(1,"(") + toStr(e1,1,0) + "=>" + toStr(e2,1,1) + par(1,")")
  31. case Iff(e1, e2) => par(1,"(") + toStr(e1,1,0) + "<=>" + toStr(e2,1,1) + par(1,")") }
  32. }
  33.  
  34. def simplify(expr: Expr): Expr = {
  35.  
  36. def simplifyH(expr: Expr) = expr match {
  37. case Not( Const(true)) => Const(false) case Not(Const(false)) => Const(true)
  38. case And(p, Const(false)) => Const(false) case And(Const(false), p) => Const(false)
  39. case And(p, Const(true)) => p case And(Const(true), p) => p
  40. case Or(p, Const(false)) => p case Or(Const(false), p) => p
  41. case Or(p, Const(true)) => Const(true) case Or(Const(true), p) => Const(true)
  42. case Imp(p, Const(true)) => Const(true) case Imp(Const(true), p) => p
  43. case Imp(p, Const(false)) => Not(p) case Imp(Const(false), p) => Const(true)
  44. case Iff(p, Const(true)) => p case Iff(Const(true), p) => p
  45. case Iff(p, Const(false)) => Not(p) case Iff(Const(false), p) => Not(p)
  46. case Not(Not(p)) => p case e => e }
  47.  
  48. expr match {
  49. case Not(p) => simplifyH(Not(simplify(p)))
  50. case And(p, q) => simplifyH(And(simplify(p), simplify(q)))
  51. case Or(p, q) => simplifyH( Or(simplify(p), simplify(q)))
  52. case Iff(p, q) => simplifyH(Iff(simplify(p), simplify(q)))
  53. case Imp(p, q) => simplifyH(Imp(simplify(p), simplify(q))) case e => e }
  54. }
  55.  
  56. def nnf(expr: Expr): Expr = expr match {
  57. case And(p, q) => And(nnf(p), nnf(q)) case Or(p, q) => Or(nnf(p), nnf(q))
  58. case Imp(p, q) => Or(nnf(Not(p)), nnf(q))
  59. case Iff(p, q) => Or(And(nnf(p), nnf(q)), And(nnf(Not(p)), nnf(Not(q))))
  60. case Not(Not(p)) => nnf(p)
  61. case Not(And(p, q)) => Or(nnf(Not(p)), nnf(Not(q)))
  62. case Not( Or(p, q)) => And(nnf(Not(p)), nnf(Not(q)))
  63. case Not(Imp(p, q)) => And(nnf(p), nnf(Not(q)))
  64. case Not(Iff(p, q)) => Or(And(nnf(p), nnf(Not(q))), And(nnf(Not(p)), nnf(q))) case e => e }
  65.  
  66. def cnf(expr: Expr): Expr = {
  67.  
  68. def distr(expr: Expr): Expr = expr match {
  69. case Or(And(p, q), And(r, s)) => And(And(distr(Or(p, r)), distr(Or(p, s))),
  70. And(distr(Or(q, r)), distr(Or(q, s))))
  71. case Or(p, And(q, r)) => And(distr(Or(p, q)), distr(Or(p, r)))
  72. case Or(And(p, q), r) => And(distr(Or(p, r)), distr(Or(q, r))) case e => e }
  73.  
  74. expr match {
  75. case Or(p, q) => distr(Or(cnf(p), cnf(q))) case And(p, q) => And(cnf(p), cnf(q)) case e => e }
  76. }
  77.  
  78. def lcnf(expr: Expr): List[List[Expr]] = {
  79.  
  80. def lcnfH1(list: List[Expr], expr: Expr): List[Expr] = expr match {
  81. case And(p, q) => list ::: lcnfH1(List(), p) ::: lcnfH1(List(), q) case e => e :: list }
  82. def lcnfH2(list: List[Expr])(expr: Expr): List[Expr] = expr match {
  83. case Or(p, q) => list ::: lcnfH2(List())(p) ::: lcnfH2(List())(q) case e => e :: list }
  84.  
  85. lcnfH1(List(), expr) map lcnfH2(List())_
  86. }
  87.  
  88. def resolution(clist: List[List[Expr]]): Boolean = {
  89.  
  90. def isAtom(expr: Expr) = expr match { case Atom(_) => true case _ => false }
  91. def removeNot(expr: Expr) = expr match { case Not(p) => p
  92. case Const(false) => Const(true) case Const(true) => Const(false) }
  93. def splitClause(clause: List[Expr]) = {
  94. val (pos, neg) = clause partition (isAtom _) ; List(pos, neg map (removeNot _)) }
  95. def isTrueClause(clause: List[Expr]) = { val List(lits, nlits) = splitClause(clause)
  96. ((lits map ((e: Expr) => nlits exists ( _ == e))) :\ false)(_||_) }
  97. def isLitTrueClause(clause: List[Expr]) = clause match {
  98. case List(Const(true)) => true case List(Not(Const(false))) => true case _ => false }
  99. def simplifyClause(clause: List[Expr]) = if (isTrueClause(clause)) List(Const(true)) else clause
  100. def simplifyLcnf(clist: List[List[Expr]]) = {
  101. (clist map (simplifyClause _)) remove (isLitTrueClause _) }
  102. def negateLit(e: Expr) = e match { case Not(p) => p case p => Not(p) }
  103.  
  104. def s2l[T](set: Set[T]) = set.toList ; def l2s[T](list: List[T]) = list.toSet
  105.  
  106. def resolutionH2(tp4: (List[Expr], List[List[Expr]], List[List[Expr]], Boolean), lit: Expr) = {
  107. val (c, cs, d, b) = tp4 ; if (d == List()) (c, cs, d, b) else {
  108. val nlit = negateLit(lit) ; val c1 = c diff List(lit)
  109. val cs1 = (cs filter ((c: List[Expr]) => c exists (_ == nlit))) map (_ diff List(nlit))
  110. var d1 = cs1 map (_ ::: c1) ; val cs2h = ((cs map l2s) union (d1 map l2s)).distinct
  111. val cs2 = (cs2h map s2l) remove (isTrueClause _) ; d1 = cs2 diff cs
  112. val b1 = if (d1.isEmpty) false else (d1 exists (_ == List()) ) ; (c, cs2, d1, b1)
  113. }
  114. }
  115.  
  116. def resolutionH1(c: List[Expr], cs: List[List[Expr]], d: List[List[Expr]], b: Boolean): Boolean =
  117. (c, cs, d, b) match {
  118. case (_, List(), _, _) => false case (_, _, _, true) => true
  119. case (List(), c::cs, d, b) => resolutionH1(c, cs, d, b)
  120. case (c, cs, d, b) => {
  121. val (c1, cs1, d1, b1) = ((c, cs, d ++ List(List(Atom(""))), b) /: c)(resolutionH2)
  122. resolutionH1(List(), cs1, d1, b1) } }
  123.  
  124. clist match {
  125. case List(Const(false)::rest) => true
  126. case _ => resolutionH1(List(), simplifyLcnf(clist) map
  127. ((c: List[Expr]) => s2l(l2s(c))), List(), false) }
  128. }
  129.  
  130. def main(args: Array[String]) {
  131.  
  132. var input = ""
  133.  
  134. do { input = readLine() ; if (input != null && input != "") {
  135.  
  136. val output = parseAll(expr, input) match {
  137. case Failure(msg, _) => "failure: " + msg case Error(msg, _) => "error: " + msg
  138. case Success(parsed, _) => {
  139. val nResRet = resolution(lcnf(cnf(simplify(nnf(simplify(Not(parsed)))))))
  140. val pResRet = resolution(lcnf(cnf(simplify(nnf(simplify(parsed))))))
  141. toStr(parsed, 0, 0) + "\n" +
  142. (if (nResRet) "true" else if (pResRet) "false" else "it depends")
  143. }
  144. }
  145.  
  146. println(output) }
  147. } while (input != null && input != "")
  148. }
  149. }
Success #stdin #stdout 0.52s 248448KB
stdin
(a\/b)/\(a=>c)/\(b=>c)=>c
~((a\/b)/\(a=>c)/\(b=>c)=>c)
a/\b/\c=>a\/b\/c
a\/b=>a/\b
a\/~a<=>#T
b/\~b<=>#F
((a/\b)=>c)<=>(a=>(b=>c))
a/\b\/~a\/~b
((a\/b)=>c)<=>(a=>(b=>c))
a/\b/\c<=>~(a\/b\/c)
stdout
a\/b/\(a=>c)/\(b=>c)=>c
true
~(a\/b/\(a=>c)/\(b=>c)=>c)
false
a/\b/\c=>a\/b\/c
true
a\/b=>a/\b
it depends
a\/~a<=>#true
true
b/\~b<=>#false
true
a/\b=>c<=>(a=>(b=>c))
true
a/\b\/~a\/~b
true
a\/b=>c<=>(a=>(b=>c))
it depends
a/\b/\c<=>~(a\/b\/c)
it depends