<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-18547335</id><updated>2011-06-07T09:35:14.840-05:00</updated><title type='text'>rici</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://ricilake.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18547335/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://ricilake.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>rici</name><uri>http://www.blogger.com/profile/09426333354710933577</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>1</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-18547335.post-1262826912274938307</id><published>2007-10-22T16:40:00.000-05:00</published><updated>2007-10-22T19:06:49.272-05:00</updated><title type='text'>Iterating bits in Lua</title><content type='html'>&lt;p&gt;Today's question on &lt;a href="irc://chat.freenode.net/#lua"&gt;#lua&lt;/a&gt; was (roughly speaking): &lt;i&gt;How do you make a truth table in Lua?&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;OK, Lua has no bit operators, and it may not be the best language for intensive bit manipulation. Still, you can go a long way with the &lt;code&gt;%&lt;/code&gt; operator:&lt;/p&gt;

&lt;div class="code"&gt;&lt;code class="lua"&gt;
function bit(p)
  return 2 ^ (p - 1)  -- 1-based indexing
end

-- Typical call:  if hasbit(x, bit(3)) then ...
function hasbit(x, p)
  return x % (p + p) &gt;= p       
end

function setbit(x, p)
  return hasbit(x, p) and x or x + p
end

function clearbit(x, p)
  return hasbit(x, p) and x - p or x
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;As a digression, we could trivially use &lt;code&gt;hasbit&lt;/code&gt; to iterate over a number and implement bitwise functions:&lt;/p&gt;

&lt;div class="code"&gt;&lt;code class="lua"&gt;
function bitor(x, y)
  local p = 1; local z = 0; local limit = x &gt; y and x or y
  while p &lt;= limit do
    if hasbit(x, p) or hasbit(y, p) then
      z = z + p
    end
    p = p + p
  end
  return z
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;We can improve on that by working across the numbers from the high-order end:&lt;/p&gt;

&lt;div class="code"&gt;&lt;code class="lua"&gt;
function bitor(x, y)
  local p = 1
  while p &lt; x do p = p + p end
  while p &lt; y do p = p + p end
  local z = 0
  repeat
    if p &lt;= x or p &lt;= y then
      z = z + p
      if p &lt;= x then x = x - p end
      if p &lt;= y then y = y - p end
    end
    p = p * 0.5
  until p &lt; 1
  return z
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;Now, let's consider what a truth table function might look like. We want to compute (and display) the value of some boolean function &lt;code&gt;f&lt;/code&gt; of &lt;code&gt;n&lt;/code&gt; parameters for every combination of parameters (i.e. &lt;code&gt;2^n&lt;/code&gt; values). So our first pass might be something like this, where &lt;code&gt;explode&lt;/code&gt; explodes a number into booleans, and &lt;code&gt;TF&lt;/code&gt; prints its boolean arguments as &lt;code&gt;"T"&lt;/code&gt; or &lt;code&gt;"F"&lt;/code&gt;.&lt;/p&gt;

&lt;div class="code"&gt;&lt;code class="lua"&gt;
function truth(n, f)
  for i = 0, 2^n - 1 do
    TF(explode(i, n)); io.write" = "; TF(f(explode(i, n))); io.write"\n"
  end
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;We already know how to explode a number into bits; we've done the iteration above in &lt;code&gt;bitor&lt;/code&gt;. Here, we'll use a cute technique for recursively constructing a result list. (Unfortunately, the stack manipulation done by the Lua VM makes this technique quadratic in the number of return values even though it's a tail recursion, but for small lists it's fine.)&lt;/p&gt;

&lt;div class="code"&gt;&lt;code class="lua"&gt;
do
  -- The helper function assumes that x &lt; 2*p
  local function explode_aux(x, p)
    if p &gt;= 1 then
      if p &lt;= x then
        return true, explode_aux(x - p, p * .5)
      else
        return false, explode_aux(x, p * .5)
      end
    end
  end

  function explode(x, n)
    local p = bit(n)
    return explode_aux(x % (p + p), p)
  end
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;The function &lt;code&gt;TF&lt;/code&gt; just outputs its arguments, but it uses a similar vararg recursion. We check the &lt;i&gt;second&lt;/i&gt; argument first, since we need to know whether we'll need to output a space or not.&lt;/p&gt;

&lt;div class="code"&gt;&lt;code class="lua"&gt;
-- Output boolean values as "T" or "F"
function TF(b1, b2, ...)
  if b2 ~= nil then
    io.write(b1 and "T " or "F ")
    return TF(b2, ...)
  elseif b1 ~= nil then
    return io.write(b1 and "T" or "F")
  end
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;And this does work as expected:&lt;/p&gt;

&lt;div class='code'&gt;&lt;code&gt;
&gt; truth(2, function(a, b) return a or b end)
F F = F
F T = T
T F = T
T T = T
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;But perhaps all this bit manipulation was a distraction. After all, there is a perfectly simple recursive solution to the problem of generating all combinations of &lt;code&gt;n&lt;/code&gt; boolean values: generate &lt;code class="code_constant"&gt;false&lt;/code&gt; prepended to all the combinations of &lt;code&gt;n-1&lt;/code&gt; values, and then generate &lt;code class="code_constant"&gt;true&lt;/code&gt; prepended to all the combinations of &lt;code&gt;n-1&lt;/code&gt; values. (Moreover, this technique is easily extensible to enumerations other than booleans.)&lt;/p&gt;

&lt;p&gt;The usual way of doing this in Lua involves creating a temporary table for the list of values, but it can be done in a purely functional style, which is more fun.&lt;/p&gt;

&lt;p&gt;We want to call some function &lt;code&gt;f&lt;/code&gt; with all combinations of &lt;code&gt;n&lt;/code&gt; boolean variables. The recursion will therefore need to call some functions &lt;code&gt;g0&lt;/code&gt; and &lt;code&gt;g1&lt;/code&gt; with all combinations of &lt;code&gt;n-1&lt;/code&gt; boolean variables, where &lt;code&gt;g0&lt;/code&gt; ends up prepending &lt;code class="code_constant"&gt;false&lt;/code&gt; to the eventual arguments, and &lt;code&gt;g1&lt;/code&gt; does similarly with &lt;code class="code_constant"&gt;true&lt;/code&gt;. That's just a partial evaluation of &lt;code&gt;f&lt;/code&gt;, so we can write it like this:&lt;/p&gt;

&lt;div class="code"&gt;&lt;code class="lua"&gt;
local function g0(f) return function(...) return f(false, ...) end end
local function g1(f) return function(...) return f(true, ...) end end
local function do_each_boolean(n, f)
  if n == 0 then
    return f()
  else
    do_each_boolean(n-1, g0(f))
    do_each_boolean(n-1, g1(f))
  end
end
&lt;/code&gt;&lt;/div&gt;

&lt;p&gt;In Lua, it's often convenient to use iterators rather than mapping functions like the above. The beauty of Lua is that it is trivial to turn that function into an iterator; we just wrap it in a coroutine and provide &lt;code&gt;coroutine.yield&lt;/code&gt; as the second argument:&lt;/p&gt;

&lt;div class="code"&gt;&lt;code class="lua"&gt;
function all_booleans(n)
  return coroutine.wrap(do_each_boolean), n, coroutine.yield
end

&gt; for a, b, c in all_booleans(3) do print(a, b, c) end
false   false   false
false   false   true
false   true    false
false   true    true
true    false   false
true    false   true
true    true    false
true    true    true
&lt;/code&gt;&lt;/div&gt;

I put all of that together as a little cgi program, so you can try it out at &lt;a href="http://segundo.ricilake.net/apps/truth"&gt;http://segundo.ricilake.net/apps/truth&lt;/a&gt;. The full code is just under 100 lines; for your viewing pleasure, here it is:

&lt;div class="code"&gt;&lt;code class="lua"&gt;
local function g1(f) return function(...) return f(true, ...) end end
local function g0(f) return function(...) return f(false, ...) end end
local function bits(n, f)
  if n == 0 then
    return f()
  else
    bits(n-1, g0(f))
    bits(n-1, g1(f))
  end
end

local tc = table.concat
local function cc(h, ...) return tc({...}, h) end
local function tablerow(h, ...)
  return cc(h, "  &amp;lt;tr&amp;gt;&amp;lt;"," class='col1'&amp;gt;")
         ..cc(cc(h, "&amp;lt;/","&amp;gt;&amp;lt;"," class='colx'&amp;gt;"), ...)
         ..cc(h, "&amp;lt;/", "&amp;gt;&amp;lt;/tr&amp;gt;")   
end

local bool2char = {[true] = "T", [false] = "F"}
local function TF(x, ...)
  if x ~= nil then return bool2char[x], TF(...) end
end

local ok = {["and"] = true, ["or"] = true, ["not"] = true}
function ttable(expr)
  local seen = {}
  expr:gsub("%a%w*", function(w)
    if not ok[w] then
      if #w == 1 then
        if not seen[w] then
          seen[#seen+1] = w; seen[w] = true
        end
      else
        error "Invalid expression"
      end
    end
  end)
  if #seen &amp;gt; 6 then error "Invalid expression" end
  local f = assert(
              loadstring(
                "return function("..tc(seen, ", ")..") return "..expr.." end"),
              "Invalid expression")()
  local out = {"&amp;lt;table&amp;gt;", tablerow("th", expr, unpack(seen))}
  bits(#seen, function(...)
                  out[#out+1] = tablerow("td", TF(f(...), ...))
              end
  )
  out[#out+1] = "&amp;lt;/table&amp;gt;"
  return tc(out, "\n")
end

local function form(me, e)
  return "&amp;lt;form action='"..me.."'&amp;gt;"
         .."&amp;lt;input type='submit' value='New expression'/&amp;gt;"
         .."&amp;lt;input type='text' size='40' name='expr' value='"..(e or "").."' /&amp;gt;"
         .."&amp;lt;/form&amp;gt;"
end

local explain = [[
&amp;lt;p&amp;gt;Enter a boolean formula in the text box. You may use up to six
variables, which may only be a single letter, and the operators
&amp;lt;code&amp;gt;and&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;or&amp;lt;/code&amp;gt;, and &amp;lt;code&amp;gt;not&amp;lt;/code&amp;gt;. You may
also use comparison operators &amp;lt;code&amp;gt;==&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;~=&amp;lt;/code&amp;gt;;
the latter is equivalent to exclusive or.&amp;lt;/p&amp;gt;
&amp;lt;p&amp;gt;Note that the variables are iterated in the order they appear
in the formula&amp;lt;/p&amp;gt;
]]

local function doit(me, e)
  if e then
    e = e:gsub("%+", " "):gsub("%%20", " ")
    if e:match"&amp;lt;&amp;gt;&amp;amp;" then e = nil end
  end
  local frm = form(me, e)
  local table = e and ttable(e) or ""
  local title = e and "Truth table for '"..e.."'" or "Truth table generator"
  return cc("\n",'&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"',
                 '"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&amp;gt;',
                 "&amp;lt;html&amp;gt;",
                 "&amp;lt;head&amp;gt;",
                 "&amp;lt;title&amp;gt;"..title.."&amp;lt;/title&amp;gt;",
                 "&amp;lt;style type='text/css'&amp;gt;",
                 "table {margin-bottom:1em; table-layout:auto; border:inset 2px}",
                 "th {width:3em; border:solid 1px}",
                 "th.col1 {width:8em; border:solid 1px}",
                 "td {text-align:center; border:solid 1px}",
                 "td.col1 {font-weight: bold}",
                 "&amp;lt;/style&amp;gt;",
                 "&amp;lt;/head&amp;gt;",
                 "&amp;lt;body&amp;gt;", table, explain, frm, "&amp;lt;/body&amp;gt;",
                 "&amp;lt;/html&amp;gt;"
  )
end
local me = os.getenv"SCRIPT_NAME"
local e = os.getenv"QUERY_STRING":match("expr=([^&amp;amp;]*)")
                                 :gsub("%%(%x%x)",
                                       function(xx)
                                         return string.char(tonumber(xx, 16))
                                       end)
local ok, rv = pcall(doit, me, e)
if not ok then ok, rv = pcall(doit, me) end
io.write("Status: 200\r\nContent-type: text/html\r\n\r\n", rv)
&lt;/code&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18547335-1262826912274938307?l=ricilake.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://ricilake.blogspot.com/feeds/1262826912274938307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18547335&amp;postID=1262826912274938307' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18547335/posts/default/1262826912274938307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18547335/posts/default/1262826912274938307'/><link rel='alternate' type='text/html' href='http://ricilake.blogspot.com/2007/10/iterating-bits-in-lua.html' title='Iterating bits in Lua'/><author><name>rici</name><uri>http://www.blogger.com/profile/09426333354710933577</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
