-
-
Save navicore/a2bce19fb55f3edac5e7228eb30921c2 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)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment