Question: parsing question. How to check expression contains a symbol only as function of some specific function?

Given an expression expr, and symbol, say y I wanted to check that y only shows as argument to a specific Maple function. In this case, say ln() just an example but this can be any other function.

But if y shows up in the expression but not as argument to ln() then I want to detect this also. So the function is passed the expression and the symbol name, and it returns true or false. 

True means the symbol y only shows inside ln and false means it found y in the expression but not inside ln()

I can find all indets where the symbol shows inside the function. But the problem is how to find if the symbol shows outside of the function?

I think I need to use depends() somehow. But could not figure out how do far. Below is the code I have and few test examples and the result expected.

is_symbol_inside_func_only:=proc(expr::anything,f,y::symbol)::truefalse;
local the_type:=`Or`(     
          'specfunc( `&*`(anything,identical(y)), f )',  
          'specfunc( identical(y), f )'  ,
          'specfunc( `&+`(anything,identical(y)), f )'
          );
local T;
T:=indets(expr, the_type );
print(T);

#need to check that y does not show any where inside expression unless 
#as argument to f

RETURN(true); #or RETURN(false);
end proc:

Here some test cases

expr:=3*ln(1+y)+ln(3*y)*y+ln(y)+cos(7*y);
is_symbol_inside_func_only(expr,ln,y); #should return false

expr:=3*ln(1+y)+ln(3*y);
is_symbol_inside_func_only(expr,ln,y); #should return true

expr:=ln(y)+ln(3*y)+cos(y);
is_symbol_inside_func_only(expr,ln,y); #should return false


expr:=3+cos(y);
is_symbol_inside_func_only(expr,cos,y); #should return true

expr:=y+ln(y);
is_symbol_inside_func_only(expr,ln,y); #should return false

expr:=-1/2*ln(y-1)+1/3*ln(y)+1/6*ln(y-3):
is_symbol_inside_func_only(expr,ln,y); #should return true

some context: I wanted to apply exponential to an expression to convert all ln(y)+ln(1+y)+...  to exp(...) to make it easy to process.

But wanted to do this ONLY if all terms that has y are functions on ln otherwise, I will not raise it to exp in this case. The expression will always have the symbol y in it. So need to worry about this case. 

Update

After asking the question, I thought about using selectremove and it seems to do what I want. But need to test it more.

is_symbol_inside_func_only:=proc(expr::anything,f,y::symbol)::truefalse;
local the_type:=`Or`(     
          'specfunc( `&*`(anything,identical(y)), f )',  
          'specfunc( identical(y), f )'  ,
          'specfunc( `&+`(anything,identical(y)), f )'
          );
local hasF,nothasF;
hasF,nothasF:=selectremove(hastype,expr,the_type);
if has(nothasF,y) then
   RETURN(false);
else
   RETURN(true);
fi;
end proc:

Here is the result

expr:=3*ln(1+y)+ln(3*y)*y+ln(y)+cos(7*y):
is_symbol_inside_func_only(expr,ln,y); #should return false

expr:=3*ln(1+y)+ln(3*y):
is_symbol_inside_func_only(expr,ln,y); #should return true

expr:=ln(y)+ln(3*y)+cos(y):
is_symbol_inside_func_only(expr,ln,y); #should return false

expr:=3+cos(y):
is_symbol_inside_func_only(expr,cos,y); #should return true

expr:=y+ln(y):
is_symbol_inside_func_only(expr,ln,y); #should return false

expr:=-1/2*ln(y-1)+1/3*ln(y)+1/6*ln(y-3):
is_symbol_inside_func_only(expr,ln,y); #should return true


 

Update

I just found my function has a bug. I added one more test case. so you can ignore my function and use any of the other ones given in the answers below.

 

Maple 2023.2.1

Please Wait...