// rw3sat.scala
// import scala.language.implicitConversions
type Literal
= (Int, Boolean
) def apply
(index
: Int, flag
: Boolean
): Literal
= (index, flag
) def unapply
(l
: Literal
) = Some
(l
) }
type Clause
= Seq
[Literal
] def apply
(literals
: Literal
*): Clause
= literals
}
def apply
(clauses
: Clause
*): CNF
= clauses
}
// implicit def isSatisfiedToBoolean[A](v: IsSatisfied[A]): Boolean = v match {
// case Satisfied => true
// case Unsatisfied(_) => false
// }
def eval
(l
: Literal
)(x
: Seq
[Boolean
]): Boolean
= { b ^ x(i)
}
def eval
(c
: Clause
)(x
: Seq
[Boolean
]): Boolean
= c.exists(eval(_)(x))
def eval
(f
: CNF
)(x
: Seq
[Boolean
]): IsSatisfied
[CNF
] = f.
filterNot(eval
(_)(x
)) match { case fs
=> Unsatisfied
(fs
) }
def sample
[A
](a
: Seq
[A
]): A
= a
(Random.
nextInt(a.
length))
def w4
(n
: Int
): Seq
[Boolean
] = for (_ <-
0 until n
) yield Random.
nextBoolean // W4
def rw3sat
(f
: CNF, n
: Int, r
: Int
): String
= { @annotation.tailrec
def loop
(k
: Int, r
: Int, x
: Seq
[Boolean
]): Option
[Seq
[Boolean
]] = (eval
(f
)(x
), k, r
) match { case (Satisfied,
_,
_) => Some
(x
) // W7,W8 case (_,
0,
0) => None
// W17 case (_,
0,
_) => loop
(n
* 3, r -
1, w4
(n
)) // W15,W16 case (Unsatisfied
(fs
),
_,
_) => { val c
= sample
(fs
) // W10 val Literal
(index,
_) = sample
(c
) // W11 val x2
= x.
updated(index,
!x
(index
)) // W12 loop(k - 1, r, x2) // W13,W14
}
}
loop
(n
* 3, r, w4
(n
)) match { // W2,W3,W5,W6 case Some
(x
) => "Satisfiable with [" + x.
mkString(",") +
"]" // "充足可能である" case _ => "Probably Unsatisfiable" // "おそらく充足不可能である" }
}
def main
(args
: Array
[String
]): Unit
= {
val f
= CNF
(p1, p2, p3, p4, p5, p6, p7, p8
) // val f = CNF(p1, p2, p3, p4, p5, p6, p8)
println(rw3sat(f, 4, 3))
// => Probably Unsatisfiable
}
}
Ly8gcnczc2F0LnNjYWxhCgppbXBvcnQgc2NhbGEudXRpbC5SYW5kb20KLy8gaW1wb3J0IHNjYWxhLmxhbmd1YWdlLmltcGxpY2l0Q29udmVyc2lvbnMKCm9iamVjdCBNYWluIHsKICB0eXBlIExpdGVyYWwgPSAoSW50LCBCb29sZWFuKQogIG9iamVjdCBMaXRlcmFsIHsKICAgIGRlZiBhcHBseShpbmRleDogSW50LCBmbGFnOiBCb29sZWFuKTogTGl0ZXJhbCA9IChpbmRleCwgZmxhZykKICAgIGRlZiB1bmFwcGx5KGw6IExpdGVyYWwpID0gU29tZShsKQogIH0KCiAgdHlwZSBDbGF1c2UgPSBTZXFbTGl0ZXJhbF0KICBvYmplY3QgQ2xhdXNlIHsKICAgIGRlZiBhcHBseShsaXRlcmFsczogTGl0ZXJhbCopOiBDbGF1c2UgPSBsaXRlcmFscwogIH0KCiAgdHlwZSBDTkYgPSBTZXFbQ2xhdXNlXQogIG9iamVjdCBDTkYgewogICAgZGVmIGFwcGx5KGNsYXVzZXM6IENsYXVzZSopOiBDTkYgPSBjbGF1c2VzCiAgfQoKICB0cmFpdCBJc1NhdGlzZmllZFsrQV0KICBjYXNlIG9iamVjdCBTYXRpc2ZpZWQgZXh0ZW5kcyBJc1NhdGlzZmllZFtOb3RoaW5nXQogIGNhc2UgY2xhc3MgVW5zYXRpc2ZpZWRbQV0oeDogQSkgZXh0ZW5kcyBJc1NhdGlzZmllZFtBXQogIC8vIGltcGxpY2l0IGRlZiBpc1NhdGlzZmllZFRvQm9vbGVhbltBXSh2OiBJc1NhdGlzZmllZFtBXSk6IEJvb2xlYW4gPSB2IG1hdGNoIHsKICAvLyAgIGNhc2UgU2F0aXNmaWVkID0+IHRydWUKICAvLyAgIGNhc2UgVW5zYXRpc2ZpZWQoXykgPT4gZmFsc2UKICAvLyB9CgogIGRlZiBldmFsKGw6IExpdGVyYWwpKHg6IFNlcVtCb29sZWFuXSk6IEJvb2xlYW4gPSB7CiAgICB2YWwgTGl0ZXJhbChpLCBiKSA9IGwKICAgIGIgXiB4KGkpCiAgfQogIGRlZiBldmFsKGM6IENsYXVzZSkoeDogU2VxW0Jvb2xlYW5dKTogQm9vbGVhbiA9IAogICAgYy5leGlzdHMoZXZhbChfKSh4KSkKICBkZWYgZXZhbChmOiBDTkYpKHg6IFNlcVtCb29sZWFuXSk6IElzU2F0aXNmaWVkW0NORl0gPQogICAgZi5maWx0ZXJOb3QoZXZhbChfKSh4KSkgbWF0Y2ggewogICAgICBjYXNlIE5pbCA9PiBTYXRpc2ZpZWQKICAgICAgY2FzZSBmcyA9PiBVbnNhdGlzZmllZChmcykKICAgIH0KCiAgZGVmIHNhbXBsZVtBXShhOiBTZXFbQV0pOiBBID0gYShSYW5kb20ubmV4dEludChhLmxlbmd0aCkpCgogIGRlZiB3NChuOiBJbnQpOiBTZXFbQm9vbGVhbl0gPSBmb3IgKF8gPC0gMCB1bnRpbCBuKSB5aWVsZCBSYW5kb20ubmV4dEJvb2xlYW4gIC8vIFc0CgogIGRlZiBydzNzYXQoZjogQ05GLCBuOiBJbnQsIHI6IEludCk6IFN0cmluZyA9IHsKICAgIEBhbm5vdGF0aW9uLnRhaWxyZWMKICAgIGRlZiBsb29wKGs6IEludCwgcjogSW50LCB4OiBTZXFbQm9vbGVhbl0pOiBPcHRpb25bU2VxW0Jvb2xlYW5dXSA9IAogICAgICAoZXZhbChmKSh4KSwgaywgcikgbWF0Y2ggewogICAgICAgIGNhc2UgKFNhdGlzZmllZCwgXywgXykgPT4gU29tZSh4KSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFc3LFc4CiAgICAgICAgY2FzZSAoXywgMCwgMCkgPT4gTm9uZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gVzE3CiAgICAgICAgY2FzZSAoXywgMCwgXykgPT4gbG9vcChuICogMywgciAtIDEsIHc0KG4pKSAgICAgICAgICAgICAgICAgLy8gVzE1LFcxNgogICAgICAgIGNhc2UgKFVuc2F0aXNmaWVkKGZzKSwgXywgXykgPT4gewogICAgICAgICAgdmFsIGMgPSBzYW1wbGUoZnMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFcxMAogICAgICAgICAgdmFsIExpdGVyYWwoaW5kZXgsIF8pID0gc2FtcGxlKGMpICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFcxMQogICAgICAgICAgdmFsIHgyID0geC51cGRhdGVkKGluZGV4LCAheChpbmRleCkpICAgICAgICAgICAgICAgICAgICAgIC8vIFcxMgogICAgICAgICAgbG9vcChrIC0gMSwgciwgeDIpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFcxMyxXMTQKICAgICAgICB9CiAgICAgIH0KCiAgICBsb29wKG4gKiAzLCByLCB3NChuKSkgbWF0Y2ggeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXMixXMyxXNSxXNgogICAgICBjYXNlIFNvbWUoeCkgPT4gIlNhdGlzZmlhYmxlIHdpdGggWyIgKyB4Lm1rU3RyaW5nKCIsIikgKyAiXSIgICAvLyAi5YWF6Laz5Y+v6IO944Gn44GC44KLIgogICAgICBjYXNlIF8gPT4gIlByb2JhYmx5IFVuc2F0aXNmaWFibGUiICAgIC8vICLjgYrjgZ3jgonjgY/lhYXotrPkuI3lj6/og73jgafjgYLjgosiCiAgICB9CiAgfQoKICBkZWYgbWFpbihhcmdzOiBBcnJheVtTdHJpbmddKTogVW5pdCA9IHsKICAgIHZhbCBwMSA9IENsYXVzZShMaXRlcmFsKDAsIGZhbHNlKSwgTGl0ZXJhbCgxLCBmYWxzZSksIExpdGVyYWwoMiwgZmFsc2UpKQogICAgdmFsIHAyID0gQ2xhdXNlKExpdGVyYWwoMywgZmFsc2UpLCBMaXRlcmFsKDEsIGZhbHNlKSwgTGl0ZXJhbCgyLCB0cnVlICkpCiAgICB2YWwgcDMgPSBDbGF1c2UoTGl0ZXJhbCgwLCB0cnVlICksIExpdGVyYWwoMywgZmFsc2UpLCBMaXRlcmFsKDIsIGZhbHNlKSkKICAgIHZhbCBwNCA9IENsYXVzZShMaXRlcmFsKDAsIHRydWUgKSwgTGl0ZXJhbCgzLCB0cnVlICksIExpdGVyYWwoMSwgZmFsc2UpKQogICAgdmFsIHA1ID0gQ2xhdXNlKExpdGVyYWwoMywgdHJ1ZSApLCBMaXRlcmFsKDEsIHRydWUgKSwgTGl0ZXJhbCgyLCBmYWxzZSkpCiAgICB2YWwgcDYgPSBDbGF1c2UoTGl0ZXJhbCgwLCB0cnVlICksIExpdGVyYWwoMSwgdHJ1ZSApLCBMaXRlcmFsKDIsIHRydWUgKSkKICAgIHZhbCBwNyA9IENsYXVzZShMaXRlcmFsKDAsIGZhbHNlKSwgTGl0ZXJhbCgzLCB0cnVlICksIExpdGVyYWwoMiwgdHJ1ZSApKQogICAgdmFsIHA4ID0gQ2xhdXNlKExpdGVyYWwoMCwgZmFsc2UpLCBMaXRlcmFsKDMsIGZhbHNlKSwgTGl0ZXJhbCgxLCB0cnVlICkpCgogICAgdmFsIGYgPSBDTkYocDEsIHAyLCBwMywgcDQsIHA1LCBwNiwgcDcsIHA4KQogICAgLy8gdmFsIGYgPSBDTkYocDEsIHAyLCBwMywgcDQsIHA1LCBwNiwgcDgpCiAgICBwcmludGxuKHJ3M3NhdChmLCA0LCAzKSkKICAgIC8vID0+IFByb2JhYmx5IFVuc2F0aXNmaWFibGUKICB9Cn0=