Skip to content

Instantly share code, notes, and snippets.

@mjf
Last active April 29, 2025 09:52
Show Gist options
  • Save mjf/3057e4476f64b75951bfc2b3d7fa5a2b to your computer and use it in GitHub Desktop.
Save mjf/3057e4476f64b75951bfc2b3d7fa5a2b to your computer and use it in GitHub Desktop.
Allen's Interval Algebra implemented in pure Lua
-- Allen's Interval Algebra implemented in pure Lua
-- Copyright (C) 2025 Matouš Jan Fialka, <https://mjf.cz/>
-- Released under the terms of the "MIT" License
local interval = {}
interval.__index = interval
function interval:new(from, to, cmp)
cmp = cmp or function(a, b)
if a < b then
return -1
elseif a > b then
return 1
else
return 0
end
end
local function lt(a, b)
return cmp(a, b) < 0
end
local function eq(a, b)
return cmp(a, b) == 0
end
if lt(to, from) then
from, to = to, from
end
local obj = setmetatable({}, self)
obj.from = from
obj.to = to
obj.cmp = cmp
obj.lt = lt
obj.eq = eq
return obj
end
function interval:precedes(other)
return self.lt(self.to, other.from)
end
function interval:meets(other)
return self.eq(self.to, other.from)
end
function interval:overlaps(other)
return self.lt(self.from, other.from)
and self.lt(other.from, self.to)
and self.lt(self.to, other.to)
end
function interval:finishedby(other)
return self.eq(self.to, other.to)
and self.lt(self.from, other.from)
end
function interval:contains(other)
return self.lt(self.from, other.from)
and self.lt(other.to, self.to)
end
function interval:starts(other)
return self.eq(self.from, other.from)
and self.lt(self.to, other.to)
end
function interval:equals(other)
return self.eq(self.from, other.from)
and self.eq(self.to, other.to)
end
function interval:startedby(other)
return self.eq(self.from, other.from)
and self.lt(other.to, self.to)
end
function interval:during(other)
return self.lt(other.from, self.from)
and self.lt(self.to, other.to)
end
function interval:finishes(other)
return self.eq(self.to, other.to)
and self.lt(other.from, self.from)
end
function interval:overlappedby(other)
return self.lt(other.from, self.from)
and self.lt(self.from, other.to)
and self.lt(other.to, self.to)
end
function interval:metby(other)
return self.eq(self.from, other.to)
end
function interval:precededby(other)
return self.lt(other.to, self.from)
end
function interval:relations(other)
return {
precedes = self:precedes(other),
meets = self:meets(other),
overlaps = self:overlaps(other),
finishedby = self:finishedby(other),
contains = self:contains(other),
starts = self:starts(other),
equals = self:equals(other),
startedby = self:startedby(other),
during = self:during(other),
finishes = self:finishes(other),
overlappedby = self:overlappedby(other),
metby = self:metby(other),
precededby = self:precededby(other)
}
end
return interval
-- vi:ft=lua
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment