local function Gap(t, i) if not t[i] then return i else return Gap(t, i + 1) end end local function Gaps(t, i) return Gap, t, i end --Data structure supporting fast ordered insertion and search. local function Order() local o = {} local list = { val = nil, prev = nil, next = nil } o.Get = function( x ) end o.GetAdjacent = function( node ) return node.prev.val, node.next.val end o.Insert = function( x ) if not list.val then list.val = x return list end local node = list while node and node.val < x do node = node.next end end return o end --Construct an isomorphism between two countable dense total orders --these orders are specified by functions which return the next element in some enumeration --these elements must be comparable with comparison operators <, >, &c. local function Isomorphism( Enumeration, InverseEnumeration, inv ) --Exported table. local t = {} local enum, order, mapping, inverse --Another Isomorphism structure, --which contains the image of this isomorphism and the inverse --isomorphism mapping back to our dense countable linear order. inverse = inv or Isomorphism( InverseEnumeration, nil, t ) --Array for caching and lazily evaluating the supplied Enumeration, --an iterator that enumerates the elements of a dense countable linear order. enum = { Enumeration() } setmetatable(enum, {__index = function(_, i) for j = #enum + 1, i do enum[j] = Enumeration() end return rawget( enum, i ) end}) t.enum = enum --Expose as field --Structure supporting fast ordered insertion and search. --Values are i such that mapping[order[i]] is not nil, --sorted according to getmetatable( enum[i] ).__lt order = { 1 } --Find the indices i and k such that --enum[i] is the greatest lower bound on enum[j] in the mapping's support --enum[k] is the least upper bound on enum[j] in the mapping's support local function GetBounds( leaf ) end --Array defining isomorphism mapping this dense countable order to the one in inverse. --If mapping[i] = j, then f(enum[i]) = inverse.enum[j] mapping = { 1 } setmetatable( mapping, {__newindex = function(map, k, v) rawset(mapping, k, v) end}) --Iterates over the natural numbers outside the isomorphism's support, --so returns the least n such that n >= i and mapping[n] == nil. --(Warning, infinite loop! Make sure to break out of this.) local function NextGap(i) if not mapping[i] then return i else return NextGap(i + 1) end --tail-recursive end --Include another point in the mapping's support. --Infinite loop: ))<<>>(( function t.ExpandMap() local gapIdx = NextGap(1) local pred, succ = GetBounds( OrderedInsertion( gapIdx ) ) mapping[gapIdx] = inverse.AddNextBetween( i, mapping[pred], mapping[succ] ) return inverse.ExpandMap() end --Find the first j such that mapping[j] == nil, --enum[lower] < enum[j] < enum[upper] --Then map j to i, and add j to the order. function t.AddNextBetween( i, lower, upper ) local p, q, r, j = enum[lower], nil, enum[upper], nil for k in Gaps( 1 ) do q = enum[k] if ((not p) or (p < q)) and ((not r) or (q < r)) then j = k break end end mapping[j] = i OrderedInsertion(j) return j end --Get the isomorphism as a dictionary, for plotting. function t.GetMapping( ) local map = {} for idx, imageIdx in pairs( mapping ) do map[ enum[ idx ] ] = inverse.enum[ imageIdx ] end return map end return t end return setmetatable( { Isomorphism = Isomorphism }, {__call = Isomorphism } )