Skip to content

Instantly share code, notes, and snippets.

@fpersson
Forked from randrews/facts.lua
Created September 9, 2011 21:34
Show Gist options
  • Save fpersson/1207399 to your computer and use it in GitHub Desktop.
Save fpersson/1207399 to your computer and use it in GitHub Desktop.
Make Lua look like Prolog!
----------------------------------------------------------------------------------------------------
--- Making Lua look like Prolog:
---
--- Let's use metatables for something other than emulating prototype-based OO. By making the
--- __index metamethod create values for undefined things, we can make Lua look like Prolog!
--- We create empty tables for anything starting with a capital letter, functions that populate
--- those tables for lowercase things (to assign relationships) and if a name begins with "is_"
--- then it becomes a function that queries those tables.
----------------------------------------------------------------------------------------------------
setmetatable(_G,{ __index =
function(globals, name)
if name:match("^[A-Z]") then -- entity
rawset(globals, name, { })
elseif name:match("^is_") then -- predicate
local pred = make_predicate(name)
rawset(globals, name, pred)
else -- rule
local rule = make_rule(name)
rawset(globals, name, rule)
end
return rawget(globals, name)
end })
function make_predicate(name)
local rule = name:match("^is_(.*)")
return function(a, b)
return b[rule] == a
end
end
function make_rule(name)
return function(a, b)
a[name .. "_of"] = b
b[name] = a
end
end
----------------------------------------------------------------------------------------------------
--- Example: ---------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
father(Vader, Luke)
father(Vader, Leia)
friend(Vader, Emperor)
friend(Emperor, Vader)
friend(Han, Luke)
friend(Luke, Han)
brother(Luke, Leia)
sister(Leia, Luke)
assert(is_father(Vader, Luke))
assert(is_sister(Leia, Luke))
assert(is_friend(Han, Luke))
assert(is_friend(Luke, Han))
assert(not is_friend(Vader, Luke))
assert(not is_friend(Han, Jabba))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment