Dear MaplePrimes community,

I am currently struggling to use the simplify-command in my toolbox for symbolic generation of robot dynamics.

I created a procedure which calls the simplify command with some extra checks. There are symbolic expressions in the term to be simplified that also occur in the workspace of the worksheet calling the procedure.

The simplify command (called from within the procedure) shall regard them as symbolic expressions unaware of the content of the variable in the workspace. Nevertheless, the simplifications are performed with the global variables, even though they are declared local to the procedure.

Minimal example: The variable "l1" stands for "length 1" in a mechanic problem as well as "length of the expression"

restart:
with(LinearAlgebra): with(ArrayTools): with(codegen): with(CodeGeneration): with(StringTools):
read proc_simplify2:
T := m2*(l1+l2)*(qD2)^2: # dummy-expression for kinetic energy
l1 := length(T);
T_simpl := simplify2(T):
l2 := length(T_simpl);

Code for the file proc_simplify2:

simplify2 := proc (Term)
# Simplify a term. Additionally check if the simplification is advantageous.
# In some cases the term gets longer after the simplification. Then discard.
# Give the local procedure variable a long name. They must not be identical in Term.
local simplify_tmpvar_c1, simplify_tmpvar_c1sum, simplify_tmpvar_c2, \
simplify_tmpvar_c2sum, simplify_tmpvar_nms, simplify_tmpvar_k, Term2:
# Assume all contents of the Term to be local variables to this procedure
# Otherwise, variables like "l1" can be overwritten by occurences in the calling worksheet.
simplify_tmpvar_nms:=convert(indets(Term,name),list): # get list of symbols
for simplify_tmpvar_k from 1 to ColumnDimension(simplify_tmpvar_nms) do
if simplify_tmpvar_nms[simplify_tmpvar_k] = Pi or simplify_tmpvar_nms[simplify_tmpvar_k] = 0 then
next: # 0 and Pi can not be variables
end if:
eval(sprintf("local %s;", String(simplify_tmpvar_nms[simplify_tmpvar_k]))); # assume local
end do:
# Get computational effort before simplification
simplify_tmpvar_c1:=add(cost~(Term)):
simplify_tmpvar_c1sum := diff(simplify_tmpvar_c1,functions)+ \
diff(simplify_tmpvar_c1,additions)+ \
diff(simplify_tmpvar_c1,multiplications)+\
diff(simplify_tmpvar_c1,divisions):
# Perform simplification. Attention: tries to use global variables to simplify the expression (see above)
Term2 := simplify(Term):
# Get effort after simplification
simplify_tmpvar_c2:=add(cost~(Term2)):
simplify_tmpvar_c2sum := diff(simplify_tmpvar_c2,functions)+\
diff(simplify_tmpvar_c2,additions)+\
diff(simplify_tmpvar_c2,multiplications)+\
diff(simplify_tmpvar_c2,divisions):
if simplify_tmpvar_c2sum > simplify_tmpvar_c1sum then
# The simplification was not successful. Take old version.
Term2 := Term:
end if:
return Term2:
end proc:

I would be glad for suggestions how to define the symbolic expressions in Term as local to the procedure or perhaps a better way to perform simplifications. As my program extends over several worksheets and the user may define an input file, I would not like to have to control all names of temporary variables that may occur at some point in the project. Until I tried to use the simplify-command, there was no problem regarding variable names. Is it perhaps possible that the variables are now only declared local in the for loop and not in the procedure?