4.40 Examples how to match types

These are examples how to match expression types

  1. expr is product a*b which is matched using

    type(a*b,`&*`(anything,anything)) 
                 true
     
    
    The above can also be written using infix notation
    type(a*b,  anything &* anything) 
                 true
     
    
    However, the above only match product of two terms. To match 3*a*b use
    type(3*a*b,`*`) 
                 true
     
    
  2. expr is division a/b which is matched using same as `*`

    type(a/b,`&*`(anything,anything)) 
                 true
     
    
  3. Match type of a*f(x), which is anything times a function that takes one argument \(x\).

    type(a*f(x),`&*`(anything,patfunc(identical(x),anything))) 
                 true
     
    
    Using patfunc is better than using function
    type(a*f(x,y),`&*`(anything,function(identical(x)))) 
                 true
     
    
    Because patfunc matches on \(f(x,y,z,\dots )\) and not just function which takes only one argument \(f(x)\). But if you know your function takes only one argument, then use function
  4. To match 3*y/x. This was tricky. Had to use

    expr:=3*y/x; 
    type(expr, `&*`(anything,identical(y),`^`(identical(x),-1))) 
             or 
    type(expr, `&*`(identical(y),`^`(identical(x),-1))) 
     
                 true
     
    
    I used or to account for possible expr:=y/x, i.e. missing constant at front. Note that
    expr:=3*y/x; 
    type(3*y/x, `&*`(anything,identical(y/x))) 
                false
                                                                                      
                                                                                      
     
    
    Does not match, since 3*y/x is actually 3*y times 1/x internally.
  5. Match on f(b* y/x)

    type(f(3*y/x),function(`&*`(anything,identical(y),`^`(identical(x),-1)))) 
     
                true
     
    
  6. Match on f(b* y/x) or f(y/x)

    expr:=f(3*y/x); 
    type(expr, function(`&*`(anything,identical(y),`^`(identical(x),-1)))) 
       or 
    type(expr, function(`&*`(identical(y),`^`(identical(x),-1)))) 
     
                true
     
    
    Again, had to use or to account for missing constant multiplier.
  7. Match on a*f(b* y/x)

    expr:=a*f(3*y/x); 
    type(expr, `&*`(anything,patfunc(`&*`(anything,identical(y),`^`(identical(x),-1))))) 
      true
     
    
  8. Match against 9+3 y/x

    expr:=9+3*y/x; 
    selector:=`&+`(anything,`&*`(anything,identical(y),`^`(identical(x),-1))): 
    type(expr, selector); 
     
                 true 
     
    select(type,[expr],selector); 
         [9 + 3*y/x]
     
    
    Notice in the above, when using select we need to put the expression inside a list, as select looks at each operand, This way the whole expression is taken as one. If we just used select(type,expr,selector); it would not have found it.

    To use patmatch the command becomes

    patmatch(expr, a::anything+b::anything*y/x,'la'); 
    la 
     
        [a = 9, b = 3]
     
    
    The nice thing about patmatch is that it allowed one to assign variable to parts of the expression automatically.
  9. Match against 9+f(3 y/x) where now \(f\) is function. Using patmatch. I could not do this in one command, as all my attempts failed:

    expr:=3+4*x*f(3*y/x); 
    body_of_function:=C::anything*y/x; 
    patmatch(expr,A::anything+B::anything*F::function(C::anything*y/x),'la'); 
    patmatch(expr,A::anything+B::anything*F::patfunc(C::anything*y/x),'la'); 
     
    Error, (in PatternMatching:-AlgStruct:-Match) testing against an invalid type 
    Error, (in type/patfunc) testing against an invalid type
     
    
    So I had to do it in two steps. First match on the function as whole, then use that to match on f(3*y/x) in second stage, like this
    expr:=3+4*x*f(3*y/x); 
    patmatch(expr,A::anything+B::anything*F::function(anything),'la'); 
    la; 
     
    [A = 3, B = 4*x, F = f(3*y/x)]
     
    

    And now

    assign(la); 
    A:='A'; 
    patmatch (op(1,F),A::anything*y/x,'la'); 
    la 
     
    [A = 3]
     
    

Overall, I find Mathematica’s pattern matching constructs much simpler and more intuitive to use and easier to learn as there are many examples and tutorials. For example, the last example above in Mathematica could be done as follows

expr=9+(4*x)*f[3*y/x]; 
Cases[{expr},any0_.+ any1_.*any2_[any3_.*y/x]:>{any0,any1,any2,any3}] 
 
{{9, 4 x, f, 3}}
 

Maple’s help pages are not good at all and provide little or no examples to learn from compared to Mathematica’s excellent help pages. For any serious pattern matching tasks, I would use Mathematica. Maple has a better debugger and hence easier to debug the code because of this. So it is a trade between these two systems.