Actualización del motor algebraico para permitir asignaciones duales, integrando ecuaciones en el contexto de SymPy. Se mejora la gestión de variables y se optimiza la lógica de resolución, asegurando que las soluciones se apliquen correctamente al sistema. Se actualiza el historial de cálculos con nuevas expresiones.
This commit is contained in:
parent
242d5095af
commit
b7e35d1ae3
|
@ -1,9 +1,12 @@
|
||||||
|
|
||||||
61.6/2.54
|
x=t**2+5/m
|
||||||
|
t=?
|
||||||
|
|
||||||
|
m=3
|
||||||
|
x=4
|
||||||
|
|
||||||
|
t=?
|
||||||
|
|
||||||
k=2.54
|
|
||||||
|
|
||||||
1080/1440
|
|
||||||
|
|
||||||
1920/(3/4)
|
|
||||||
|
|
||||||
|
|
|
@ -350,7 +350,7 @@ class PureAlgebraicEngine:
|
||||||
return EvaluationResult(line, error_msg, "error", False, str(e), is_solve_query=True)
|
return EvaluationResult(line, error_msg, "error", False, str(e), is_solve_query=True)
|
||||||
|
|
||||||
def _evaluate_assignment(self, line: str) -> EvaluationResult:
|
def _evaluate_assignment(self, line: str) -> EvaluationResult:
|
||||||
"""Evalúa una asignación"""
|
"""Evalúa una asignación CON FUNCIONALIDAD DUAL: asignación al contexto + ecuación a sympy"""
|
||||||
try:
|
try:
|
||||||
var_name, expression_str = line.split('=', 1)
|
var_name, expression_str = line.split('=', 1)
|
||||||
var_name = var_name.strip()
|
var_name = var_name.strip()
|
||||||
|
@ -367,10 +367,30 @@ class PureAlgebraicEngine:
|
||||||
eval_context = self._get_complete_context()
|
eval_context = self._get_complete_context()
|
||||||
result_obj = sympify(expression_str, locals=eval_context)
|
result_obj = sympify(expression_str, locals=eval_context)
|
||||||
|
|
||||||
# Actualizar tabla de símbolos
|
# 1. ASIGNACIÓN AL CONTEXTO (para evaluación directa)
|
||||||
self.symbol_table[var_name] = result_obj
|
self.symbol_table[var_name] = result_obj
|
||||||
self.variables.add(var_name)
|
self.variables.add(var_name)
|
||||||
|
|
||||||
|
# 2. AGREGAR COMO ECUACIÓN A SYMPY (para resolución algebraica)
|
||||||
|
try:
|
||||||
|
# Crear el símbolo de la variable y la ecuación simbólica
|
||||||
|
var_symbol = sp.Symbol(var_name)
|
||||||
|
right_expr = sympify(expression_str, locals=eval_context)
|
||||||
|
equation_obj = Eq(var_symbol, right_expr)
|
||||||
|
|
||||||
|
# Agregar a la lista de ecuaciones para resolución
|
||||||
|
self.equations.append(equation_obj)
|
||||||
|
|
||||||
|
# Registrar símbolos de la ecuación
|
||||||
|
for free_symbol in equation_obj.free_symbols:
|
||||||
|
self.variables.add(str(free_symbol))
|
||||||
|
|
||||||
|
self.logger.debug(f"Asignación dual agregada: {var_name} = {result_obj} (como ecuación: {equation_obj})")
|
||||||
|
|
||||||
|
except Exception as eq_error:
|
||||||
|
# Si falla como ecuación, continuar solo con la asignación
|
||||||
|
self.logger.warning(f"No se pudo agregar '{line}' como ecuación: {eq_error}")
|
||||||
|
|
||||||
output = f"{var_name} = {result_obj}"
|
output = f"{var_name} = {result_obj}"
|
||||||
|
|
||||||
# Devolver el resultado de la asignación
|
# Devolver el resultado de la asignación
|
||||||
|
@ -514,21 +534,53 @@ class PureAlgebraicEngine:
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return f"Error resolviendo sistema: {e}"
|
return f"Error resolviendo sistema: {e}"
|
||||||
elif len(args) == 1 and hasattr(args[0], 'is_Symbol') and args[0].is_Symbol:
|
elif len(args) == 1 and hasattr(args[0], 'is_Symbol') and args[0].is_Symbol:
|
||||||
# solve(variable) - resolver para una variable específica y auto-aplicar
|
# solve(variable) - resolver para una variable específica
|
||||||
var_symbol = args[0]
|
var_symbol = args[0]
|
||||||
solution_value = self._solve_for_variable(var_symbol)
|
solution_value = self._solve_for_variable(var_symbol)
|
||||||
|
|
||||||
# Si encontramos una solución, auto-aplicar al sistema
|
# Si encontramos una solución diferente de la variable
|
||||||
if solution_value != var_symbol:
|
if solution_value != var_symbol:
|
||||||
# Resolver iterativamente para obtener el valor más simplificado
|
# Verificar si la solución contiene otras variables
|
||||||
|
free_symbols = solution_value.free_symbols
|
||||||
|
unresolved_vars = free_symbols - {var_symbol}
|
||||||
|
|
||||||
|
if unresolved_vars:
|
||||||
|
# Hay variables sin resolver, verificar si tienen valores numéricos
|
||||||
|
has_numeric_values = True
|
||||||
|
for var_sym in unresolved_vars:
|
||||||
|
var_name = str(var_sym)
|
||||||
|
if var_name in self.symbol_table:
|
||||||
|
value = self.symbol_table[var_name]
|
||||||
|
# Si el valor es simbólico (no numérico), no podemos resolver completamente
|
||||||
|
if not (hasattr(value, 'is_number') and value.is_number):
|
||||||
|
has_numeric_values = False
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# Variable no tiene valor asignado
|
||||||
|
has_numeric_values = False
|
||||||
|
break
|
||||||
|
|
||||||
|
if has_numeric_values:
|
||||||
|
# Todas las variables tienen valores numéricos, resolver iterativamente
|
||||||
final_value = self._resolve_iteratively(solution_value)
|
final_value = self._resolve_iteratively(solution_value)
|
||||||
|
|
||||||
# Auto-aplicar la solución al sistema
|
# Auto-aplicar la solución numérica al sistema
|
||||||
|
if final_value != var_symbol and not str(final_value) in ['True', 'False']:
|
||||||
self._auto_apply_solution(var_symbol, final_value)
|
self._auto_apply_solution(var_symbol, final_value)
|
||||||
|
|
||||||
# Verificar que el resultado no sea problemático
|
return Eq(var_symbol, final_value)
|
||||||
if final_value == var_symbol or str(final_value) in ['True', 'False']:
|
else:
|
||||||
return var_symbol
|
# Hay variables con valores simbólicos, mostrar la relación algebraica
|
||||||
|
# Ejemplo: t = x - 5 (donde x = t + 5, es simbólico)
|
||||||
|
result_eq = Eq(var_symbol, solution_value)
|
||||||
|
return result_eq
|
||||||
|
else:
|
||||||
|
# No hay variables sin resolver, intentar resolver completamente
|
||||||
|
final_value = self._resolve_iteratively(solution_value)
|
||||||
|
|
||||||
|
# Auto-aplicar la solución al sistema solo si es un valor específico
|
||||||
|
if final_value != var_symbol and not str(final_value) in ['True', 'False']:
|
||||||
|
self._auto_apply_solution(var_symbol, final_value)
|
||||||
|
|
||||||
return Eq(var_symbol, final_value)
|
return Eq(var_symbol, final_value)
|
||||||
else:
|
else:
|
||||||
|
@ -536,9 +588,12 @@ class PureAlgebraicEngine:
|
||||||
var_name = str(var_symbol)
|
var_name = str(var_symbol)
|
||||||
if var_name in self.symbol_table:
|
if var_name in self.symbol_table:
|
||||||
value = self.symbol_table[var_name]
|
value = self.symbol_table[var_name]
|
||||||
|
# Si el valor en symbol_table es diferente de la variable, devolverlo
|
||||||
|
if value != var_symbol:
|
||||||
final_value = self._resolve_iteratively(value)
|
final_value = self._resolve_iteratively(value)
|
||||||
return Eq(var_symbol, final_value)
|
return Eq(var_symbol, final_value)
|
||||||
else:
|
|
||||||
|
# Si no hay información, devolver la variable tal como está
|
||||||
return var_symbol
|
return var_symbol
|
||||||
else:
|
else:
|
||||||
# solve() con argumentos específicos (múltiples variables, ecuaciones, etc.)
|
# solve() con argumentos específicos (múltiples variables, ecuaciones, etc.)
|
||||||
|
@ -550,13 +605,7 @@ class PureAlgebraicEngine:
|
||||||
return var_symbol
|
return var_symbol
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# 1. Buscar si la variable tiene asignación directa en symbol_table
|
# 1. Buscar ecuaciones que contengan esta variable PRIMERO
|
||||||
var_name = str(var_symbol)
|
|
||||||
if var_name in self.symbol_table:
|
|
||||||
# Devolver el valor de la asignación directa
|
|
||||||
return self.symbol_table[var_name]
|
|
||||||
|
|
||||||
# 2. Buscar ecuaciones que contengan esta variable
|
|
||||||
relevant_eqs = [eq for eq in self.equations if var_symbol in eq.free_symbols]
|
relevant_eqs = [eq for eq in self.equations if var_symbol in eq.free_symbols]
|
||||||
if relevant_eqs:
|
if relevant_eqs:
|
||||||
# Estrategia 1: Buscar asignación directa
|
# Estrategia 1: Buscar asignación directa
|
||||||
|
@ -585,7 +634,8 @@ class PureAlgebraicEngine:
|
||||||
# en términos de otras variables
|
# en términos de otras variables
|
||||||
try:
|
try:
|
||||||
# Obtener todas las variables del sistema excepto la que queremos resolver
|
# Obtener todas las variables del sistema excepto la que queremos resolver
|
||||||
all_vars = list(self.variables)
|
# Convertir todas las variables a símbolos para sympy
|
||||||
|
all_vars = [sp.Symbol(v) if isinstance(v, str) else v for v in self.variables]
|
||||||
other_vars = [v for v in all_vars if v != var_symbol]
|
other_vars = [v for v in all_vars if v != var_symbol]
|
||||||
|
|
||||||
if other_vars:
|
if other_vars:
|
||||||
|
@ -624,7 +674,15 @@ class PureAlgebraicEngine:
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# 5. Si nada funciona, devolver la variable tal como está
|
# 5. Si no hay ecuaciones relevantes, buscar en symbol_table como último recurso
|
||||||
|
var_name = str(var_symbol)
|
||||||
|
if var_name in self.symbol_table:
|
||||||
|
value = self.symbol_table[var_name]
|
||||||
|
# Solo devolver si el valor no es la misma variable (evitar bucles)
|
||||||
|
if value != var_symbol:
|
||||||
|
return value
|
||||||
|
|
||||||
|
# 6. Si nada funciona, devolver la variable tal como está
|
||||||
return var_symbol
|
return var_symbol
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|
Loading…
Reference in New Issue