from ironflow.model import dtypes, NodeInputBP, NodeOutputBP
from ironflow.model.node import Node
[docs]class OperatorNodeBase(Node):
version = "v0.0"
init_inputs = [
NodeInputBP(dtype=dtypes.Data(size="s")),
NodeInputBP(dtype=dtypes.Data(size="s")),
]
init_outputs = [
NodeOutputBP(),
]
style = "small"
def __init__(self, params):
super().__init__(params)
self.num_inputs = 0
self.actions["add input"] = {"method": self.add_operand_input}
[docs] def place_event(self):
for i in range(len(self.inputs)):
self.register_new_operand_input(i)
[docs] def rebuild_remove_actions(self):
remove_keys = []
for k, v in self.actions.items():
if k.startswith("remove input"):
remove_keys.append(k)
for k in remove_keys:
del self.actions[k]
for i in range(self.num_inputs):
self.actions[f"remove input {i}"] = {
"method": self.remove_operand_input,
"data": i,
}
[docs] def update_event(self, inp=-1):
self.set_output_val(
0, self.apply_op([self.input(i) for i in range(len(self.inputs))])
)
[docs] def apply_op(self, elements: list):
return None
# LOGIC -------------------------------------
[docs]class LogicNodeBase(OperatorNodeBase):
color = "#f58142"
[docs]class NOT_Node(LogicNodeBase):
title = "not"
[docs] def apply_op(self, elements: list):
return all([not bool(e) for e in elements])
[docs]class AND_Node(LogicNodeBase):
title = "and"
[docs] def apply_op(self, elements: list):
return all(elements)
[docs]class NAND_Node(LogicNodeBase):
title = "nand"
[docs] def apply_op(self, elements: list):
return not all(elements)
[docs]class OR_Node(LogicNodeBase):
title = "or"
[docs] def apply_op(self, elements: list):
return any(elements)
[docs]class NOR_Node(LogicNodeBase):
title = "nor"
[docs] def apply_op(self, elements: list):
return not any(elements)
[docs]class XOR_Node(LogicNodeBase):
title = "xor"
[docs] def apply_op(self, elements: list):
# XOR definition for unbound number of operands:
# odd number of operands must be true
return len(list(filter((lambda x: bool(x)), elements))) % 2 != 0
[docs]class XNOR_Node(LogicNodeBase):
title = "xnor"
[docs] def apply_op(self, elements: list):
# XNOR definition for unbound number of operands:
# even number of operands must be true
return len(list(filter((lambda x: bool(x)), elements))) % 2 == 0
logic_nodes = [
NOT_Node,
AND_Node,
NAND_Node,
OR_Node,
NOR_Node,
XOR_Node,
XNOR_Node,
]
# -------------------------------------------
# ARITHMETIC --------------------------------
[docs]class ArithmeticNodeBase(OperatorNodeBase):
color = "#58db53"
[docs]class Plus_Node(ArithmeticNodeBase):
title = "+"
[docs] def apply_op(self, elements: list):
v = elements[0]
for e in elements[1:]:
v = v + e
return v
# return sum(elements)
[docs]class Minus_Node(ArithmeticNodeBase):
title = "-"
[docs] def apply_op(self, elements: list):
v = elements[0]
for e in elements[1:]:
v = v - e
return v
# return sum(elements[:1])-sum(elements[1:])
[docs]class Multiply_Node(ArithmeticNodeBase):
title = "*"
[docs] def apply_op(self, elements: list):
v = elements[0]
for e in elements[1:]:
v *= e
return v
# return math.prod(elements)
[docs]class Divide_Node(ArithmeticNodeBase):
title = "/"
[docs] def apply_op(self, elements: list):
v = elements[0]
for e in elements[1:]:
v = v / e
return v
# if len(elements) > 0:
# x = elements[0]
# for e in elements[1:]:
# x /= e
# return x
# else:
# return None
[docs]class Power_Node(ArithmeticNodeBase):
title = "**"
[docs] def apply_op(self, elements: list):
v = elements[0]
for e in elements[1:]:
v = v**e
return v
# if len(elements) > 0:
# x = elements[0]
# for e in elements[1:]:
# x **= e
# return x
# else:
# return None
arithmetic_nodes = [
Plus_Node,
Minus_Node,
Multiply_Node,
Divide_Node,
Power_Node,
]
# -------------------------------------------
# COMPARATORS -------------------------------
[docs]class ComparatorNodeBase(OperatorNodeBase):
color = "#a1574c"
[docs] def apply_op(self, elements: list):
# if len(elements) > 0:
b = True
for i in range(1, len(elements)):
b = b and (self.comp(elements[i - 1], elements[i]))
return b
# return None
[docs] def comp(self, a, b) -> bool:
return False
[docs]class Equal_Node(ComparatorNodeBase):
title = "=="
[docs] def comp(self, a, b) -> bool:
return a == b
[docs]class NotEqual_Node(ComparatorNodeBase):
title = "!="
[docs] def comp(self, a, b) -> bool:
return a != b
[docs]class Greater_Node(ComparatorNodeBase):
title = ">"
[docs] def comp(self, a, b) -> bool:
return a > b
[docs]class GreaterEq_Node(ComparatorNodeBase):
title = ">="
[docs] def comp(self, a, b) -> bool:
return a >= b
[docs]class Less_Node(ComparatorNodeBase):
title = "<"
[docs] def comp(self, a, b) -> bool:
return a < b
[docs]class LessEq_Node(ComparatorNodeBase):
title = "<="
[docs] def comp(self, a, b) -> bool:
return a <= b
comparator_nodes = [
Equal_Node,
NotEqual_Node,
Greater_Node,
GreaterEq_Node,
Less_Node,
LessEq_Node,
]
# -------------------------------------------
nodes = [
*logic_nodes,
*arithmetic_nodes,
*comparator_nodes,
]