This question has some reference to the question Defining logical operator implies in lua. The following code works fine.
local function _implies(a, b)
if a == 1 and b == 0 then return 0
else return 1 end
end
local my_right = {
__mul = function(self, b)
return _implies(self.a, b)
end
}
local _mt = {
__mul = function(a)
return setmetatable({a=a}, my_right)
end
}
local my_left={}
setmetatable(my_left,_mt)
imp = my_left
local names={}
for i = 0,1 do
for j=0,1 do
names.i=i;names.j=j
print(i, j, names.i *imp* names.j)
end
end
The following code is similar to above code. It is for logical and. The question I want to ask is : Are both and_left and and_right are required in this case as well? Were they required because implies is not commutative? In other words, can the code be made somewhat efficient for defining logand?
local function _and(a, b)
if a == 1 and b == 1 then return 1
else return 0 end
end
local right_and = {
__mul = function(self, b)
return _and(self.a, b)
end
}
local and_mt = {
__mul = function(a)
return setmetatable({a=a}, right_and)
end
}
local and_left={}
setmetatable(and_left,and_mt)
log_and = and_left
local names={}
for i = 0,1 do
for j=0,1 do
names.i=i;names.j=j
print(i, j, names.i *log_and* names.j)
end
end
Note: I know bitwise operator & is there but for some reasons, I don't want to use it.
Are both and_left and and_right are required
They were introduced because there are two semantically different multiplications involved.
But the code can be optimized.
The version below does not create a new table on every multiplication.
It also uses only one metatable instead of two.
do
local function _implies(a, b)
if a == 1 and b == 0 then
return 0
else
return 1
end
end
local temp, imp = {}, {}
local _mt = {
__mul = function(a, b)
if b == imp then
temp[1] = a
return temp
elseif a == temp then
return _implies(temp[1], b)
end
end
}
setmetatable(temp, _mt)
setmetatable(imp, _mt)
_G.imp = imp
end
local names={}
for i = 0, 1 do
for j = 0, 1 do
names.i=i
names.j=j
print(i, j, names.i *imp* names.j)
end
end