fork(2) download
  1. # rw3sat.ex
  2. # http://i...content-available-to-author-only...e.com/3PzRUG
  3.  
  4. defmodule RW3SAT do
  5. :random.seed :os.timestamp
  6.  
  7. defp sample(xs) do
  8. # ref: http://c...content-available-to-author-only...g.com/entry/2015/04/20/101926
  9. Enum.at(xs, :random.uniform(Enum.count xs) - 1)
  10. end
  11.  
  12. defmodule Literal do
  13. defstruct index: 0, flag: false
  14. end
  15. defp literal(index, flag), do: %Literal{index: index, flag: flag}
  16.  
  17. defmodule Clause do
  18. defstruct literals: []
  19. end
  20. defp clause(literals), do: %Clause{literals: literals}
  21.  
  22. defmodule CNF do
  23. defstruct clauses: []
  24. end
  25. defp cnf(clauses), do: %CNF{clauses: clauses}
  26.  
  27. defp satisfied?(l = %Literal{}, x) do
  28. if l.flag, do: !Enum.at(x, l.index), else: Enum.at(x, l.index)
  29. # l.flag xor Enum.at(x, l.index)
  30. end
  31.  
  32. defp satisfied?(c = %Clause{}, x) do
  33. Enum.any?(c.literals, &(satisfied?(&1, x)))
  34. end
  35.  
  36. defp satisfied?(f = %CNF{}, x) do
  37. Enum.all?(f.clauses, &(satisfied?(&1, x)))
  38. end
  39.  
  40. defp w4(n) do # W4
  41. for _ <- 1..n, do: sample([false, true])
  42. end
  43.  
  44. defp rw3sat_loop(_, _, _, _, _, true) do # W7
  45. "充足可能である" # W8
  46. end
  47.  
  48. defp rw3sat_loop(_, _, 0, 0, _, _) do
  49. "おそらく充足不可能である" # W17
  50. end
  51.  
  52. defp rw3sat_loop(f, n, 0, r, _, _) do
  53. x = w4(n)
  54. rw3sat_loop(f, n, n * 3, r - 1, x, satisfied?(f, x)) # W15,W16
  55. end
  56.  
  57. defp rw3sat_loop(f, n, k, r, x, _) do
  58. c = f.clauses |> Enum.filter(&(!satisfied?(&1, x))) |> sample # W10
  59. %{index: i} = sample(c.literals) # W11
  60. x2 = for j <- 0..n-1 do # W12
  61. if i == j, do: !Enum.at(x, j), else: Enum.at(x, j)
  62. end
  63. rw3sat_loop(f, n, k - 1, r, x2, satisfied?(f, x2)) # W13,W14
  64. end
  65.  
  66. def rw3sat(f, n, r) do
  67. x = w4(n)
  68. rw3sat_loop(f, n, n * 3, r, x, satisfied?(f, x)) # W2,W3,W5,W6
  69. end
  70.  
  71. def main do
  72. p1 = clause([literal(0, false), literal(1, false), literal(2, false)])
  73. p2 = clause([literal(3, false), literal(1, false), literal(2, true )])
  74. p3 = clause([literal(0, true ), literal(3, false), literal(2, false)])
  75. p4 = clause([literal(0, true ), literal(3, true ), literal(1, false)])
  76. p5 = clause([literal(3, true ), literal(1, true ), literal(2, false)])
  77. p6 = clause([literal(0, true ), literal(1, true ), literal(2, true )])
  78. p7 = clause([literal(0, false), literal(3, true ), literal(2, true )])
  79. p8 = clause([literal(0, false), literal(3, false), literal(1, true )])
  80.  
  81. f = cnf([p1, p2, p3, p4, p5, p6, p7, p8])
  82. # f = cnf([p1, p2, p3, p4, p5, p6, p8])
  83. rw3sat(f, 4, 3) |> IO.puts
  84. # => おそらく充足不可能である
  85. end
  86.  
  87. end
  88.  
  89. RW3SAT.main
Success #stdin #stdout 1.03s 106688KB
stdin
Standard input is empty
stdout
おそらく充足不可能である