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

Given an expression expr, and symbol, say I wanted to check that 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 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 only shows inside ln and false means it found 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 are functions on ln otherwise, I will not raise it to exp in this case. The expression will always have the symbol 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...