function res = sym2sym(fun, var, val)
% Reemplaza una variable por la misma variable dentro de una
% función.
%
% Algunas veces, el 'subs' no funciona (no reemplaza la variable)
% Para eso, convierto la variable en texto
%
% Necesita el paquete octave-symbolic octave-strings
pkg load symbolic;
pkg load strings;
symbols;

% convertir a texto la función
fun_txt = to_char(fun);

con1 = isa(var, "cell") || isa(var, "list");
con2 = isa(val, "cell") || isa(val, "list");
con3 = isa(val, "double") && length(val)==length(var);

if con1 && con2 && length(var)==length(val)
% cuando ambas son estructuras o listas del mismo tamaño
	
	var_txt{length(var)} = " ";
	%-- Reemplazar la variable por el valor (en la función de texto)
	for i=1:length(var)
		% ver si la variable es de texto o simbólica
		if isa(var{i}, "char")
			var_txt{i} = var{i};
		elseif isa(var{i}, "sym")
			var_txt{i} = to_char(var{i});
		endif
		
		% ver si el valor es numérico
		if isa(val{i}, "double")
			val_txt = num2str(val{i});
		else
			val_txt = val{i}; %char
		endif
		
		fun_txt = strrep(fun_txt, var_txt{i}, val_txt);
	endfor
	
	%-- Regenerar las variables simbólicas
	
	%- Encontrar cuáles siguen siendo variables
	list_var_fun = findsymbols(fun);
		
	for i=1:length(list_var_fun)
		
		% esta variable existe en la función original
		var_fun = to_char(list_var_fun{i});
		
		%quiero ver si var_fun existe en fun_txt		
		if not(isempty(strfind(fun_txt, var_fun)))
		% sí existe, entonces, creo la variable simbólica
			cmd = [var_fun, "=sym(\"", var_fun, "\");"];			
			eval(cmd);
		endif	
	endfor	
	
	%-- Regenerar la función
	cmd = ["res = ", fun_txt, ";"];
	eval(cmd);
	
elseif con1 && con3
% cuando los valores son numéricos

	% convertir todo a texto y mandar llamar el caso cuando los valores son de texto
	val_txt{length(val)} = " ";
	for i=1:length(val)
		val_txt{i} = num2str(val(i));
	endfor
	res = sym2sym(fun, var, val_txt);

elseif isa(var, "char")
% cuando la variable es de texto
	var_str = {var};
	res = sym2sym(fun, var_str, val);
	
elseif isa(var, "double")
% cuando la variable es un sólo número
	var_char = num2str(var);
	res = sym2sym(fun, var_char, val);
else
	tam_var = length(var);
	tam_val = length(val);
	cl_var = class(var);
	cl_val = class(val);
	disp("sym2sym.m:");
	disp("El tipo de variable y el valor, o su longitud,\n");
	disp("no coinciden");
	disp(["variable: ", cl_var," ", tam_var]);
	error(["valor: ", cl_val," ", tam_var]);	
endif

endfunction
