Skip to content

Instantly share code, notes, and snippets.

@fpersson
Forked from randrews/facts.lua
Created September 9, 2011 21:34
Show Gist options
  • Select an option

  • Save fpersson/1207399 to your computer and use it in GitHub Desktop.

Select an option

Save fpersson/1207399 to your computer and use it in GitHub Desktop.

Revisions

  1. @randrews randrews revised this gist Apr 4, 2011. 1 changed file with 19 additions and 21 deletions.
    40 changes: 19 additions & 21 deletions facts.lua
    Original file line number Diff line number Diff line change
    @@ -8,36 +8,34 @@
    --- 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
    return b[rule] == a
    end
    end

    function make_rule(name)
    return function(a, b)
    a[name .. "_of"] = b
    b[name] = a
    end
    a[name .. "_of"] = b
    b[name] = a
    end
    end

    setmetatable(_G,{ __index =
    function(globals, name)
    if not rawget(globals, name) then
    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
    end
    return rawget(globals, name)
    end })

    ----------------------------------------------------------------------------------------------------
    --- Example: ---------------------------------------------------------------------------------------
    ----------------------------------------------------------------------------------------------------
  2. @randrews randrews created this gist Apr 1, 2011.
    62 changes: 62 additions & 0 deletions facts.lua
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,62 @@
    ----------------------------------------------------------------------------------------------------
    --- 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.
    ----------------------------------------------------------------------------------------------------

    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

    setmetatable(_G,{ __index =
    function(globals, name)
    if not rawget(globals, name) then
    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
    end
    return rawget(globals, name)
    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))