Simatic_XML_Parser_to_SCL/ToUpload/processors/process_o.py

69 lines
2.8 KiB
Python

# processors/process_o.py
# -*- coding: utf-8 -*-
import sympy
import traceback
# Usar las nuevas utilidades
from .processor_utils import get_sympy_representation
from .symbol_manager import SymbolManager
SCL_SUFFIX = "_sympy_processed" # Nuevo sufijo
def process_o(instruction, network_id, sympy_map, symbol_manager: SymbolManager, data):
"""Genera la expresión SymPy para la operación lógica O (OR)."""
instr_uid = instruction["instruction_uid"]
instr_type_original = instruction.get("type", "O")
if instr_type_original.endswith(SCL_SUFFIX) or "_error" in instr_type_original:
return False
# Buscar todas las entradas 'in', 'in1', 'in2', ...
input_pins = sorted([pin for pin in instruction.get("inputs", {}) if pin.startswith("in")])
if not input_pins:
print(f"Error: O {instr_uid} sin pines de entrada (inX).")
instruction["scl"] = f"// ERROR: O {instr_uid} sin pines inX"
instruction["type"] = instr_type_original + "_error"
return True
sympy_parts = []
all_resolved = True
for pin in input_pins:
input_info = instruction["inputs"][pin]
sympy_expr = get_sympy_representation(input_info, network_id, sympy_map, symbol_manager)
if sympy_expr is None:
all_resolved = False
# print(f"DEBUG: O {instr_uid} esperando pin {pin}")
break # Salir si una dependencia no está lista
# Optimización: No incluir FALSE en un OR
if sympy_expr != sympy.false:
sympy_parts.append(sympy_expr)
if not all_resolved:
return False # Esperar dependencias
# Construir la expresión OR de SymPy
result_sympy_expr = sympy.false # Valor por defecto si no hay entradas válidas o todas son FALSE
if sympy_parts:
# Usar sympy.Or para construir la expresión
result_sympy_expr = sympy.Or(*sympy_parts)
# Simplificar casos obvios como OR(X) -> X, OR(X, TRUE) -> TRUE
# simplify_logic aquí puede ser prematuro, mejor al final.
# Pero Or() podría simplificar automáticamente OR(X) -> X.
# Opcional: result_sympy_expr = sympy.simplify_logic(result_sympy_expr)
# Guardar la expresión SymPy resultante en el mapa para 'out'
map_key_out = (network_id, instr_uid, "out")
sympy_map[map_key_out] = result_sympy_expr
# Marcar como procesado, SCL principal es solo comentario
instruction["scl"] = f"// SymPy O: {result_sympy_expr}" # Comentario opcional
instruction["type"] = instr_type_original + SCL_SUFFIX
# La instrucción 'O' no tiene ENO propio, propaga el resultado por 'out'
return True
# --- Processor Information Function ---
def get_processor_info():
"""Devuelve la información para la operación lógica O (OR)."""
return {'type_name': 'o', 'processor_func': process_o, 'priority': 1}