Advertisement
partyboy1a

SAT-solver-framework.lua

Jan 17th, 2013
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.46 KB | None | 0 0
  1. function deepcopy(v)
  2.     if(type(v)=="table") then
  3.         local t = {}
  4.         local key, val
  5.         for key, val in pairs(t) do
  6.             t[key] = deepcopy(val)
  7.         end
  8.         return t
  9.     else
  10.         return v
  11.     end
  12. end
  13.  
  14. total_number_of_variables = 0
  15.  
  16. Var = {}
  17. num_to_var = {}
  18. function NewVar(name, entries)
  19.     local tab = {}
  20.     local ctab, ulim
  21.     if type(entries)=="table" then
  22.         temp = {}
  23.         for i=0,#entries do
  24.             temp[i] = 1
  25.         end
  26.         while(true) do
  27.             ctab = tab
  28.             for i=1,#entries-1 do
  29.                 if type(ctab[temp[i]])=="nil" then ctab[temp[i]]={} end
  30.                 ctab = ctab[temp[i]]
  31.             end
  32.             for j=1,entries[#entries] do
  33.                 total_number_of_variables = total_number_of_variables + 1
  34.                 ctab[j] = total_number_of_variables
  35.                
  36.                 local temp2 = {}
  37.                 for i=1,#entries-1 do temp2[i]=temp[i] end
  38.                 temp2[#entries] = j
  39.                 num_to_var[total_number_of_variables] = {
  40.                     name = name, entry = temp2
  41.                 }
  42.             end
  43.             temp[#entries-1] = temp[#entries-1] + 1
  44.            
  45.             ulim = #entries-1
  46.             while(ulim > 0 and temp[ulim] > entries[ulim]) do
  47.                 temp[ulim] = 1
  48.                 ulim = ulim - 1
  49.                 temp[ulim] = temp[ulim] + 1
  50.             end
  51.             if ulim == 0 then break end
  52.         end
  53.         Var[name] = tab
  54.     elseif type(entries)=="number" then
  55.         for i=1,entries do
  56.             total_number_of_variables = total_number_of_variables + 1
  57.             tab[i]= total_number_of_variables
  58.             num_to_var[total_number_of_variables] = {
  59.                 name = name, entry = i
  60.             }
  61.         end
  62.         Var[name] = tab
  63.     elseif type(entries)=="nil" then
  64.         total_number_of_variables = total_number_of_variables + 1
  65.         Var[name] = total_number_of_variables
  66.         num_to_var[total_number_of_variables] = {
  67.             name = name
  68.         }
  69.     end
  70. end
  71.  
  72. total_number_of_clauses = 0
  73. clause = {}
  74.  
  75. function CheckClause(cl)
  76.     assert(type(cl) == "table",
  77.             "ERROR: cl should be a table")
  78.     for i=1,#cl,2 do
  79.         assert(type(cl[i]) == "number",
  80.             "ERROR: cl["..i.."]="..tostring(cl[i])..", but should be a number")
  81.         assert(type(cl[i+1]) == "boolean",
  82.             "ERROR: cl["..(i+1).."]="..tostring(cl[i+1])..", but should be true or false")
  83.     end
  84. end
  85.  
  86. function AddSimpleClause(cl)
  87.     total_number_of_clauses = total_number_of_clauses + 1
  88.     CheckClause(cl)
  89.     clause[total_number_of_clauses] = cl
  90. end
  91.  
  92. function AddIfThenClause(str_if, cl1, str_then, cl2)
  93.     assert(str_if=="if" or str_if=="if ALL" or str_if=="if ONE",
  94.         "bad argument for str_if, it is "..str_if..", but must be"..
  95.         "\n  if"..
  96.         "\nOR"..
  97.         "\n  if ALL"..
  98.         "\nOR"..
  99.         "\n  if ONE")
  100.     assert(str_then=="then" or str_then=="then ALL" or str_then=="then ONE",
  101.         "bad argument for str_then, it is "..str_then..", but must be"..
  102.         "\n  then"..
  103.         "\nOR"..
  104.         "\n  then ALL"..
  105.         "\nOR"..
  106.         "\n then ONE")
  107.  
  108.     CheckClause(cl1)
  109.     CheckClause(cl2)
  110.  
  111.     local invert_cl1 = {}
  112.     for i=1,#cl1,2 do
  113.         invert_cl1[i] = cl1[i]
  114.         invert_cl1[i + 1] = not cl1[i + 1]
  115.     end    
  116.  
  117.     if str_if=="if" or str_if=="if ALL" then
  118.        
  119.         if str_then=="then" or str_then=="then ALL" then
  120.  
  121.             for i=1,#cl2,2 do
  122.                 local t = {}
  123.                 for j=1,#invert_cl1 do
  124.                     t[j] = invert_cl1[j]
  125.                 end
  126.                 t[#t+1] = cl2[i]
  127.                 t[#t+1] = cl2[i+1]
  128.                 AddSimpleClause(t)
  129.             end
  130.  
  131.         elseif str_then=="then ONE" then
  132.  
  133.             local t = {}
  134.             for j=1,#invert_cl1 do
  135.                 t[j] = invert_cl1[j]
  136.             end
  137.             for j=1,#cl2 do
  138.                 t[#t+1] = cl2[j]
  139.             end
  140.             AddSimpleClause(t)
  141.         end
  142.  
  143.     elseif str_if=="if ONE" then
  144.        
  145.         if str_then=="then" or str_then=="then ALL" then
  146.  
  147.             for i=1,#invert_cl1,2 do for j=1,#cl2,2 do
  148.                 AddSimpleClause{
  149.                     invert_cl1[i], invert_cl1[i+1],
  150.                     cl2[j], cl2[j+1]}
  151.             end end
  152.  
  153.         elseif str_then=="then ONE" then
  154.  
  155.             for i=1,#invert_cl1,2 do
  156.                 local t = {invert_cl1[i], invert_cl1[i+1]}
  157.                 for j=1,#cl2 do
  158.                     t[#t+1] = cl2[j]
  159.                 end
  160.                 AddSimpleClause(t)
  161.             end
  162.  
  163.         end
  164.     end
  165. end
  166.  
  167. function AddIfAndOnlyIfClause(str_cl1, cl1, str_ifandonlyif, str_cl2, cl2)
  168.     assert(str_cl1=="ONE of" or str_cl1=="ALL of",
  169.         "str_cl1 not specified, must be"..
  170.         "\n   ONE of"..
  171.         "\nOR"..
  172.         "\n   ALL of")
  173.     assert(str_cl2=="ONE of" or str_cl2=="ALL of",
  174.         "str_cl2 not specified, must be"..
  175.         "\n   ONE of"..
  176.         "\nOR"..
  177.         "\n   ALL of")
  178.     assert(str_ifandonlyif=="if and only if",
  179.         "str_ifandonlyif must be exactly the following string:"..
  180.         "\n   if and only if")
  181.    
  182.     CheckClause(cl1)
  183.     CheckClause(cl2)
  184.    
  185.     if str_cl1=="ALL of" then
  186.         if str_cl2=="ALL of" then
  187.             AddIfThenClause("if ALL", cl1, "then ALL", cl2)
  188.             AddIfThenClause("if ALL", cl2, "then ALL", cl1)
  189.         elseif str_cl2=="ONE of" then
  190.             AddIfThenClause("if ALL", cl1, "then ONE", cl2)
  191.             AddIfThenClause("if ONE", cl2, "then ALL", cl1)
  192.         end
  193.     elseif str_cl1=="ONE of" then
  194.         if str_cl2=="ALL of" then
  195.             AddIfThenClause("if ONE", cl1, "then ALL", cl2)
  196.             AddIfThenClause("if ALL", cl2, "then ONE", cl1)
  197.         elseif str_cl2=="ONE of" then
  198.             AddIfThenClause("if ONE", cl1, "then ONE", cl2)
  199.             AddIfThenClause("if ONE", cl2, "then ONE", cl1)
  200.         end    
  201.     end
  202. end
  203.  
  204. function WriteSATfile()
  205.     file = io.open("satfile.cnf", "w")
  206.     file.write(file, "p cnf "..total_number_of_variables.." "..total_number_of_clauses.."\n")
  207.     local s = ""
  208.     for i=1,total_number_of_clauses do
  209.         s = ""
  210.         local j = 1
  211.         while(clause[i][j] ~= nil and clause[i][j+1] ~= nil) do
  212.             if not clause[i][j+1] then s = s .. "-" end
  213.             s = s .. clause[i][j] .. " "
  214.             j = j + 2
  215.         end
  216.         file.write(file, s.."0\n")
  217.     end
  218.     file.close(file)   
  219. end
  220.  
  221. function ParseSolution()
  222.     file = io.open("solutionfile", "r")
  223.     Sol = {}
  224.     local s, lin
  225.     for lin in file.lines(file) do for s in string.gmatch(lin, "[%d%-]+") do
  226.         local b
  227.         s = s + 0
  228.         if s > 0 then
  229.             b = true
  230.         elseif s < 0 then
  231.             b = false
  232.             s = -s
  233.         else
  234.             break
  235.         end
  236.    
  237.         local con = num_to_var[s]
  238.         local name = con.name
  239.         local entry = con.entry
  240.         if type(entry)=="nil" then
  241.             Sol[name] = b
  242.         elseif type(entry)=="number" then
  243.             entry = entry + 0
  244.             if type(Sol[name])=="nil" then
  245.                 Sol[name] = {}
  246.             end
  247.             Sol[name][entry] = b
  248.         elseif type(entry)=="table" then
  249.             if type(Sol[name])=="nil" then
  250.                 Sol[name] = {}
  251.             end
  252.             local v = Sol[name]
  253.             for j = 1, #entry - 1 do
  254.                 if type(v[entry[j]])=="nil" then
  255.                     v[entry[j]] = {}
  256.                 end
  257.                 v = v[entry[j]]
  258.             end
  259.             v[entry[#entry]] = b
  260.         end
  261.     end end
  262. end
  263.  
  264. function PrintSolution()
  265.  
  266.     local function PrintVar(s, v)
  267.         if type(v)=="number" then
  268.             print(s..": ".." unknown")
  269.         elseif type(v)=="boolean" then
  270.             print(s..": "..tostring(v))
  271.         elseif type(v)=="table" then
  272.             for key, val in pairs(v) do
  273.                 PrintVar(s.."["..key.."]", val)
  274.             end
  275.         end
  276.     end
  277.     for key, val in pairs(Sol) do
  278.         PrintVar(key, val)
  279.     end
  280. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement