The following code defines sort of custom operator imp. It works almost correctly.
local function _imp(x, y)
if x == 1 and y == 0 then return 0
else return 1 end
end
local tmp = {}
local imp = {}
local imp_mult= {
__mul = function(a,b)
if b==imp then
tmp[1]=a
return tmp
elseif a == tmp then
return _imp(tmp[1], b)
end
end
}
setmetatable(tmp, imp_mult)
setmetatable(imp, imp_mult)
_G.imp = imp
print("0 imp 0 evaluates to ", 0*imp*0)
print("1 imp 0 evaluates to", 1*imp*0)
print("0 imp (1 imp 0) evaluates to", 0*imp*((1*imp*0)))
The above code outputs to
0 imp 0 evaluates to 1
1 imp 0 evaluates to 0
0 imp (1 imp 0) evaluates to 0
The first two answers are correct. However the expected answer for last expression is 1 as 0*imp*0
evaluates to 1 and 1*imp*0
evaluates to 0. Where is the mistake? How the definition of imp_mult can be improved to get expected answer?
The value of tmp[1]
will be overwritten. Instead of 1
, you should use a counter variable that is incremented before the operation is done (x * imp
), and decremented when an operation is done (x * imp * y
).
local function _imp(x, y)
if x == 1 and y == 0 then return 0
else return 1 end
end
local tmp = {}
local imp = {}
local depth = 0
local imp_mult = {
__mul = function(a,b)
if b==imp then
depth = depth + 1
tmp[depth] = a
return tmp
elseif a == tmp then
local v = _imp(tmp[depth], b)
depth = depth - 1
return v
end
end
}
setmetatable(tmp, imp_mult)
setmetatable(imp, imp_mult)
_G.imp = imp
print("0 imp 0 evaluates to ", 0*imp*0)
print("1 imp 0 evaluates to", 1*imp*0)
print("0 imp (1 imp 0) evaluates to", 0*imp*((1*imp*0)))
You can change the place of the assignment to use the 0
th index if you want to.