lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 22 September 2014 12:57, Doug Currie <doug.currie@gmail.com> wrote:
> On Mon, Sep 22, 2014 at 10:37 AM, Hisham <h@hisham.hm> wrote:
>>
>> ...
>>
>> For the archives (and the sharp debugging eyes of lua-l), here's a
>> version that handles two different [{}] keys as equivalent...
>
>
> The shortcut
>
>  if avoid_loops[t1] then return avoid_loops[t1] == t2 end
>
> uses == which looks wrong. Here's a test that fails...
>
>> t0 = {1, 2, 3}
>
>> t1 = {1, 2, 3}
>
>> t2 = {1, 2, 3}
>
>> return  table_eq({[t0] = t1, [t1] = t2, [t2] = t1}, {[t0] = t2, [t2] = t1,
>> [t2] = t2})

There's a typo in your test case: the second table defines the [t2]
key twice, so the first table has three elements and the second one
has two elements. They're not structurally equivalent. Changing to
this, however,

   table_eq({[t0] = t1, [t1] = t2, [t2] = t1}, {[t0] = t2, [t1] = t1,
[t2] = t2})

makes my code return true.

The point of the shortcut is that, if a subtable t1 matches subtable
t2 somewhere along the way, then all further matches of t1 in the
table structure must map to that same t2 from the second table, or
else they are not structurally equivalent. In other words, if we draw
those tables as a graph, they result in different plots. What I mean
is this:

local child1 = { "hello" }
local root1 = { {}, child1, { child1 } }

local child2 = { "hello" }
local root2 = { {}, child2, { child2 } }

local root3 = { {}, { "hello" }, { { "hello" } } }

assert( table_eq(root1, root2) )
assert( not table_eq(root1, root3) )

Does that make sense? (I had to come up with _some_ criterion for
equivalence...)

-- Hisham