Created
April 1, 2011 05:46
-
-
Save randrews/897798 to your computer and use it in GitHub Desktop.
Make Lua look like Prolog!
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
---------------------------------------------------------------------------------------------------- | |
--- 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)) |
@wesleywerner I updated the versions of all the plugins and wordpress a few days ago, and that broke a few things. One of the things it broke completely was the graphviz plugin, I migrated the site to a new host to fix that. But I didn't notice that it also broke my syntax-highlighting-pre-tag plugin, thank you for noticing! That post should be fixed now, I'm about to go through and fix the others.
(good news is the reason I updated everything is I'm about to start making some posts again)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I have your post on this bookmarked and always refer to it when I feel like a bit of Lua inspiration, it is a fine example. Today I noticed the code blocks are no longer rendered on the page at http://www.playwithlua.com/?p=5
As an aside -- you don't need the assignment of
a[name .. "_of"] = b
in themake_rule
function. The "_of" value gets clobbered by each call but since it is not used for relationship testing it's existence is moot.