Advertisement
partyboy1a

sat-solver-framework.lua

Jan 13th, 2016
94
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.59 KB | None | 0 0
  1. if not USE_WINDOWS and not USE_LINUX then
  2. error("you must specify the system, some code here is system dependant!")
  3. end
  4.  
  5. function deepcopy(v)
  6. if(type(v)=="table") then
  7. local t = {}
  8. local key, val
  9. for key, val in pairs(t) do
  10. t[key] = deepcopy(val)
  11. end
  12. return t
  13. else
  14. return v
  15. end
  16. end
  17.  
  18. total_number_of_variables = 0
  19.  
  20. Var = {}
  21. num_to_var = {}
  22. function NewVar(name, entries)
  23. local tab = {}
  24. local ctab, ulim
  25. if type(entries)=="table" then
  26. temp = {}
  27. for i=0,#entries do
  28. temp[i] = 1
  29. end
  30. while(true) do
  31. ctab = tab
  32. for i=1,#entries-1 do
  33. if type(ctab[temp[i]])=="nil" then ctab[temp[i]]={} end
  34. ctab = ctab[temp[i]]
  35. end
  36. for j=1,entries[#entries] do
  37. total_number_of_variables = total_number_of_variables + 1
  38. ctab[j] = total_number_of_variables
  39.  
  40. local temp2 = {}
  41. for i=1,#entries-1 do temp2[i]=temp[i] end
  42. temp2[#entries] = j
  43. num_to_var[total_number_of_variables] = {
  44. name = name, entry = temp2
  45. }
  46. end
  47. temp[#entries-1] = temp[#entries-1] + 1
  48.  
  49. ulim = #entries-1
  50. while(ulim > 0 and temp[ulim] > entries[ulim]) do
  51. temp[ulim] = 1
  52. ulim = ulim - 1
  53. temp[ulim] = temp[ulim] + 1
  54. end
  55. if ulim == 0 then break end
  56. end
  57. Var[name] = tab
  58. elseif type(entries)=="number" then
  59. for i=1,entries do
  60. total_number_of_variables = total_number_of_variables + 1
  61. tab[i]= total_number_of_variables
  62. num_to_var[total_number_of_variables] = {
  63. name = name, entry = i
  64. }
  65. end
  66. Var[name] = tab
  67. elseif type(entries)=="nil" then
  68. total_number_of_variables = total_number_of_variables + 1
  69. Var[name] = total_number_of_variables
  70. num_to_var[total_number_of_variables] = {
  71. name = name
  72. }
  73. end
  74. end
  75.  
  76. total_number_of_clauses = 0
  77. clause = {}
  78.  
  79. function CheckClause(cl)
  80. assert(type(cl) == "table",
  81. "ERROR: cl should be a table")
  82. for i=1,#cl,2 do
  83. assert(type(cl[i+1]) == "boolean",
  84. "ERROR: cl["..(i+1).."]="..tostring(cl[i+1])..", but should be true or false")
  85. assert(type(cl[i]) == "number",
  86. "ERROR: cl["..i.."]="..tostring(cl[i])..", but should be a number")
  87. end
  88. end
  89.  
  90. function AddSimpleClause(cl)
  91. total_number_of_clauses = total_number_of_clauses + 1
  92. CheckClause(cl)
  93. clause[#clause+1] = cl
  94.  
  95. if max_clauses ~= nil and #clause >= max_clauses then
  96. print(total_number_of_clauses.." clauses reached, writing...")
  97. local s = ""
  98. for i=1,#clause do
  99. s = ""
  100. local j = 1
  101. while(clause[i][j] ~= nil and clause[i][j+1] ~= nil) do
  102. if not clause[i][j+1] then s = s .. "-" end
  103. s = s .. clause[i][j] .. " "
  104. j = j + 2
  105. end
  106. clausefile.write(clausefile, s.."0\n")
  107. end
  108. clause = {}
  109. collectgarbage()
  110. print("done!")
  111. end
  112. end
  113.  
  114. function AddIfThenClause(str_if, cl1, str_then, cl2)
  115. assert(str_if=="if" or str_if=="if ALL" or str_if=="if ONE",
  116. "bad argument for str_if, it is "..str_if..", but must be"..
  117. "\n if"..
  118. "\nOR"..
  119. "\n if ALL"..
  120. "\nOR"..
  121. "\n if ONE")
  122. assert(str_then=="then" or str_then=="then ALL" or str_then=="then ONE",
  123. "bad argument for str_then, it is "..str_then..", but must be"..
  124. "\n then"..
  125. "\nOR"..
  126. "\n then ALL"..
  127. "\nOR"..
  128. "\n then ONE")
  129.  
  130. CheckClause(cl1)
  131. CheckClause(cl2)
  132.  
  133. local invert_cl1 = {}
  134. for i=1,#cl1,2 do
  135. invert_cl1[i] = cl1[i]
  136. invert_cl1[i + 1] = not cl1[i + 1]
  137. end
  138.  
  139. if str_if=="if" or str_if=="if ALL" then
  140.  
  141. if str_then=="then" or str_then=="then ALL" then
  142.  
  143. for i=1,#cl2,2 do
  144. local t = {}
  145. for j=1,#invert_cl1 do
  146. t[j] = invert_cl1[j]
  147. end
  148. t[#t+1] = cl2[i]
  149. t[#t+1] = cl2[i+1]
  150. AddSimpleClause(t)
  151. end
  152.  
  153. elseif str_then=="then ONE" then
  154.  
  155. local t = {}
  156. for j=1,#invert_cl1 do
  157. t[j] = invert_cl1[j]
  158. end
  159. for j=1,#cl2 do
  160. t[#t+1] = cl2[j]
  161. end
  162. AddSimpleClause(t)
  163. end
  164.  
  165. elseif str_if=="if ONE" then
  166.  
  167. if str_then=="then" or str_then=="then ALL" then
  168.  
  169. for i=1,#invert_cl1,2 do for j=1,#cl2,2 do
  170. AddSimpleClause{
  171. invert_cl1[i], invert_cl1[i+1],
  172. cl2[j], cl2[j+1]}
  173. end end
  174.  
  175. elseif str_then=="then ONE" then
  176.  
  177. for i=1,#invert_cl1,2 do
  178. local t = {invert_cl1[i], invert_cl1[i+1]}
  179. for j=1,#cl2 do
  180. t[#t+1] = cl2[j]
  181. end
  182. AddSimpleClause(t)
  183. end
  184.  
  185. end
  186. end
  187. end
  188.  
  189. function AddIfAndOnlyIfClause(str_cl1, cl1, str_ifandonlyif, str_cl2, cl2)
  190. assert(str_cl1=="ONE of" or str_cl1=="ALL of",
  191. "str_cl1 not specified, must be"..
  192. "\n ONE of"..
  193. "\nOR"..
  194. "\n ALL of")
  195. assert(str_cl2=="ONE of" or str_cl2=="ALL of",
  196. "str_cl2 not specified, must be"..
  197. "\n ONE of"..
  198. "\nOR"..
  199. "\n ALL of")
  200. assert(str_ifandonlyif=="if and only if",
  201. "str_ifandonlyif must be exactly the following string:"..
  202. "\n if and only if")
  203.  
  204. CheckClause(cl1)
  205. CheckClause(cl2)
  206.  
  207. if str_cl1=="ALL of" then
  208. if str_cl2=="ALL of" then
  209. AddIfThenClause("if ALL", cl1, "then ALL", cl2)
  210. AddIfThenClause("if ALL", cl2, "then ALL", cl1)
  211. elseif str_cl2=="ONE of" then
  212. AddIfThenClause("if ALL", cl1, "then ONE", cl2)
  213. AddIfThenClause("if ONE", cl2, "then ALL", cl1)
  214. end
  215. elseif str_cl1=="ONE of" then
  216. if str_cl2=="ALL of" then
  217. AddIfThenClause("if ONE", cl1, "then ALL", cl2)
  218. AddIfThenClause("if ALL", cl2, "then ONE", cl1)
  219. elseif str_cl2=="ONE of" then
  220. AddIfThenClause("if ONE", cl1, "then ONE", cl2)
  221. AddIfThenClause("if ONE", cl2, "then ONE", cl1)
  222. end
  223. end
  224. end
  225.  
  226. max_clauses = nil
  227. function StartAutoWrite(new_max_clauses)
  228. max_clauses = new_max_clauses
  229. clausefile = io.open("satfile-CLAUSES.cnf", "w")
  230. end
  231.  
  232. function WriteSATfile()
  233. file = io.open("satfile-START.cnf", "w")
  234. file.write(file, "p cnf "..total_number_of_variables.." "..total_number_of_clauses.."\n")
  235. local s = ""
  236. for i=1,#clause do
  237. s = ""
  238. local j = 1
  239. while(clause[i][j] ~= nil and clause[i][j+1] ~= nil) do
  240. if not clause[i][j+1] then s = s .. "-" end
  241. s = s .. clause[i][j] .. " "
  242. j = j + 2
  243. end
  244. file.write(file, s.."0\n")
  245. end
  246. file.close(file)
  247.  
  248. if max_clauses == nil then
  249. if USE_WINDOWS then
  250. os.execute("rename satfile-START.cnf satfile.cnf")
  251. elseif USE_LINUX then
  252. os.execute("mv satfile-START.cnf satfile.cnf")
  253. else
  254. error("function not implemented for your system!")
  255. end
  256. else
  257. clausefile.close(clausefile)
  258. if USE_WINDOWS then
  259. os.execute("copy /B satfile-START.cnf + satfile-CLAUSES.cnf satfile.cnf")
  260. os.execute("del satfile-START.cnf")
  261. os.execute("del satfile-CLAUSES.cnf")
  262. elseif USE_LINUX then
  263. os.execute("cat satfile-START.cnf satfile-CLAUSES.cnf > satfile.cnf")
  264. os.execute("rm satfile-START.cnf")
  265. os.execute("rm satfile-CLAUSES.cnf")
  266. else
  267. error("function not implemented for your system!")
  268. end
  269. end
  270. end
  271.  
  272. function ParseSolution()
  273. file = io.open("solutionfile", "r")
  274. Sol = {}
  275. local s, lin
  276. for lin in file.lines(file) do for s in string.gmatch(lin, "[%d%-]+") do
  277. local b
  278. s = s + 0
  279. if s > 0 then
  280. b = true
  281. elseif s < 0 then
  282. b = false
  283. s = -s
  284. else
  285. break
  286. end
  287.  
  288. local con = num_to_var[s]
  289. local name = con.name
  290. local entry = con.entry
  291. if type(entry)=="nil" then
  292. Sol[name] = b
  293. elseif type(entry)=="number" then
  294. entry = entry + 0
  295. if type(Sol[name])=="nil" then
  296. Sol[name] = {}
  297. end
  298. Sol[name][entry] = b
  299. elseif type(entry)=="table" then
  300. if type(Sol[name])=="nil" then
  301. Sol[name] = {}
  302. end
  303. local v = Sol[name]
  304. for j = 1, #entry - 1 do
  305. if type(v[entry[j]])=="nil" then
  306. v[entry[j]] = {}
  307. end
  308. v = v[entry[j]]
  309. end
  310. v[entry[#entry]] = b
  311. end
  312. end end
  313. end
  314.  
  315. function PrintSolution()
  316.  
  317. local function PrintVar(s, v)
  318. if type(v)=="number" then
  319. print(s..": ".." unknown")
  320. elseif type(v)=="boolean" then
  321. print(s..": "..tostring(v))
  322. elseif type(v)=="table" then
  323. for key, val in pairs(v) do
  324. PrintVar(s.."["..key.."]", val)
  325. end
  326. end
  327. end
  328. for key, val in pairs(Sol) do
  329. PrintVar(key, val)
  330. end
  331. end
  332.  
  333. NewVar("always_true")
  334. NewVar("always_false")
  335. AddSimpleClause{Var.always_false, false}
  336. AddSimpleClause{Var.always_true, true}
  337.  
  338. -- format: a1,1 a1,2 a1,3 a2,1 a2,2 a2,3 a3,1 ... an,3
  339. -- result: whenever am,1 is true, am2, am,3 will appear in the final clause
  340. function ConditionalClause(ccl)
  341. local cl = {}
  342. for i = 1, #t, 3 do
  343. assert(type(t[i]) == "boolean", "Position "..i.." is not boolean, it is "..type(t[i]).."!")
  344. assert(type(t[i+1]) == "number", "Position "..(i+1).." is not number, it is "..type(t[i+1]).."!")
  345. assert(type(t[i+2]) == "boolean", "Position "..(i+2).." is not boolean, it is "..type(t[i+2]).."!")
  346.  
  347. if t[i] then
  348. cl[#cl+1] = t[i+1]
  349. cl[#cl+1] = t[i+2]
  350. end
  351. end
  352. return cl
  353. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement