fork download
  1. // rw3sat_oo.scala
  2.  
  3. import scala.util.Random
  4.  
  5. object Main {
  6. class Literal(val index: Int, val flag: Boolean) {
  7. def apply(x: Seq[Boolean]) = this.flag ^ x(this.index)
  8. }
  9. object Literal {
  10. def apply(index: Int, flag: Boolean) = new Literal(index, flag)
  11. }
  12.  
  13. class Clause(val literals: Seq[Literal]) {
  14. def apply(x: Seq[Boolean]) = this.literals.exists(_(x))
  15. }
  16. object Clause {
  17. def apply(literals: Literal*) = new Clause(literals)
  18. }
  19.  
  20. class CNF(val clauses: Seq[Clause]) {
  21. def apply(x: Seq[Boolean]) = this.clauses.forall(_(x))
  22. }
  23. object CNF {
  24. def apply(clauses: Clause*) = new CNF(clauses)
  25. }
  26.  
  27. def sample[A](a: Seq[A]): A = a(Random.nextInt(a.length))
  28.  
  29. def w4(n: Int): Seq[Boolean] = for (_ <- 0 until n) yield Random.nextBoolean // W4
  30.  
  31. def rw3sat(f: CNF, n: Int, r: Int): String = {
  32. @annotation.tailrec
  33. def loop(k: Int, r: Int, x: Seq[Boolean]): Option[Seq[Boolean]] =
  34. (f(x), k, r) match {
  35. case (true, _, _) => Some(x) // W7,W8
  36. case (_, 0, 0) => None // W17
  37. case (_, 0, _) => loop(n * 3, r - 1, w4(n)) // W15,W16
  38. case _ => {
  39. val c = sample(f.clauses.filterNot(_(x))) // W10
  40. val index = sample(c.literals).index // W11
  41. val x2 = x.updated(index, !x(index)) // W12
  42. loop(k - 1, r, x2) // W13,W14
  43. }
  44. }
  45.  
  46. loop(n * 3, r, w4(n)) match { // W2,W3,W5,W6
  47. case Some(x) => "Satisfiable with [" + x.mkString(",") + "]" // "充足可能である"
  48. case _ => "Probably Unsatisfiable" // "おそらく充足不可能である"
  49. }
  50. }
  51.  
  52. def main(args: Array[String]): Unit = {
  53. val p1 = Clause(Literal(0, false), Literal(1, false), Literal(2, false))
  54. val p2 = Clause(Literal(3, false), Literal(1, false), Literal(2, true ))
  55. val p3 = Clause(Literal(0, true ), Literal(3, false), Literal(2, false))
  56. val p4 = Clause(Literal(0, true ), Literal(3, true ), Literal(1, false))
  57. val p5 = Clause(Literal(3, true ), Literal(1, true ), Literal(2, false))
  58. val p6 = Clause(Literal(0, true ), Literal(1, true ), Literal(2, true ))
  59. val p7 = Clause(Literal(0, false), Literal(3, true ), Literal(2, true ))
  60. val p8 = Clause(Literal(0, false), Literal(3, false), Literal(1, true ))
  61.  
  62. val f = CNF(p1, p2, p3, p4, p5, p6, p7, p8)
  63. // val f = CNF(p1, p2, p3, p4, p5, p6, p8)
  64. println(rw3sat(f, 4, 3))
  65. // => Probably Unsatisfiable
  66. }
  67. }
Success #stdin #stdout 0.37s 322240KB
stdin
Standard input is empty
stdout
Probably Unsatisfiable