1 Pattern matching

1.1 Detect reduced Riccati ode \(y'=a x^n + b y^2\)
1.2 Detect general Riccati ode \(y'=f_0(x) + f_1(x) y(x)+ f_2(x) y^2\)
1.3 Detect ode of form \(y'=(a + b x + c y(x))^n\)
1.4 pattern example 1
1.5 pattern example 2
1.6 pattern example 3
1.7 pattern example 4
1.8 pattern example 5
1.9 pattern example 6
1.10 pattern example 7
1.11 pattern example 8
1.12 pattern example 9
1.13 pattern example 10
1.14 pattern example 11
1.15 pattern example 12
1.16 pattern example 13
1.17 pattern example 14
1.18 pattern example 15
1.19 pattern example 16
1.20 pattern example 17
1.21 pattern example 18
1.22 pattern example 19

This section shows some examples using Maple to detect some patterns. In all of these the main maple function used is patmatch. Some example also show the Mathematica command.

Many of these can be done in Maple without using patmatch command, and even using shorter code. But these examples are meant to show how to use patmatch.

1.1 Detect reduced Riccati ode \(y'=a x^n + b y^2\)

This detects Reduced Riccati ode \(y'=a x^n + b y^2\) where \(a,n,b\) are scalars and \(y(x)\) is the dependent function. The input to the proc is the ode and the dependent function \(y(x)\). The parsing function will return \(a,b,n\) if successful match is found, or FAIL if ode does not match the expected pattern.

reduced_riccati_parse:=proc(ode::`=`,func::function(name),$) 
local RHS; 
local y:=op(0,func); 
local x:=op(1,func); 
local la,a,b,n; 
 
   try 
      RHS:=timelimit(30,[solve(ode,diff(y(x),x))]); 
      if nops(RHS)<>1 then RETURN(FAIL); fi; 
      RHS:=expand(RHS[1]); 
   catch: 
      RETURN(FAIL); 
   end try; 
 
   if patmatch(RHS,a::anything*x^(n::anything)+b::anything*y(x)^2,'la') then 
      assign(la); 
      if has(a,x) or has(a,y(x)) then RETURN(FAIL); fi; 
      if has(n,x) or has(n,y(x)) then RETURN(FAIL); fi; 
      if has(b,x) or has(b,y(x)) then RETURN(FAIL); fi; 
      RETURN(a,b,n); 
   else 
      RETURN(FAIL); 
   fi; 
 
end proc:
 

Example usage

ode:=diff(y(x),x)=x-1+y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
                              FAIL 
                           [_Riccati] 
 
ode:=diff(y(x),x)=x-1+y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
                              FAIL 
                           [_Riccati] 
 
ode:=diff(y(x),x)=-3*x^2+y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                            -3, 1, 2 
                     [[_Riccati, _special]] 
 
ode:=diff(y(x),x)=x^(-4)+y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                            1, 1, -4 
               [_rational, [_Riccati, _special]] 
 
ode:=diff(y(x),x)=sin(x)*x^(-4)+y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                              FAIL 
                           [_Riccati] 
 
ode:=diff(y(x),x$2)=x^(-4)+y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                              FAIL 
            [[_2nd_order, _with_linear_symmetries]] 
 
ode:=diff(y(x),x)-x^(-4)-9*y(x)^2=0: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                            1, 9, -4 
               [_rational, [_Riccati, _special]] 
 
ode:=diff(y(x),x)=1/x+x*y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                              FAIL 
                     [_rational, _Riccati] 
 
ode:=diff(y(x),x)=a*1/x+b*y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                            a, b, -1 
               [_rational, [_Riccati, _special]] 
 
ode:=diff(y(x),x)=a*x^n+b*y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
                            a, b, n 
                     [[_Riccati, _special]] 
 
ode:=diff(y(x),x)=a*x^n+y(x)+b*y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
                              FAIL 
                           [_Riccati] 
 
ode:=diff(y(x),x)=y(x)*x^n+b*y(x)^2: 
reduced_riccati_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
                              FAIL 
                          [_Bernoulli]
 

1.2 Detect general Riccati ode \(y'=f_0(x) + f_1(x) y(x)+ f_2(x) y^2\)

This detects the general Riccati ode \(y'=f_0(x) + f_1(x) y(x)+ f_2(x) y^2\)

The input to the proc is the ode and the dependent function \(y(x)\). The parsing function will return \(f_0,f_1,f_2\) if successful match is found, or FAIL if ode does not match the expected pattern.

\(f_0,f_2\) can not be zero (i.e. missing), but \(f_1\) could be missing.

In the case \(f_1=0\), either \(f_0\) or \(f_2\) or both must be functions of \(x\). Also in the case of \(f_1=0\), if it is reduced Riccati, then it return FAIL.

In the case \(f_1\) is present and also depends on \(x\), then now \(f_0,f_2\) are both allowed not to be functions of \(x\). But if \(f_1\) present and also does not depend on \(x\), then now at least one of \(f_0,f_2\) must be function of \(x\).

general_riccati_parse:=proc(ode::`=`,func::function(name),$) 
local RHS; 
local y:=op(0,func); 
local x:=op(1,func); 
local stat; 
local la,f0,f1,f2; 
 
   stat:= reduced_riccati_parse(ode,func); 
   if stat<>FAIL then #this is reduced riccati, hence not general 
      RETURN(FAIL); 
   fi; 
 
   #now check if general riccati 
   try 
      RHS:=timelimit(30,[solve(ode,diff(y(x),x))]); 
      if nops(RHS)<>1 then RETURN(FAIL); fi; 
      RHS:=expand(RHS[1]); 
      RHS:=collect(RHS,[y(x),y(x)^2]);#must collect to insure the right form 
   catch: 
      RETURN(FAIL); 
   end try; 
 
   if patmatch(RHS,f0::anything+f1::anything*y(x)+f2::anything*y(x)^2,'la') then 
      assign(la); 
      if f0=0 or f2=0 then RETURN(FAIL); fi; 
      if has(f0,y(x)) or has(f1,y(x)) or has(f2,y(x)) then RETURN(FAIL); fi; 
 
      if has(f1,x) then 
         RETURN(f0,f1,f2); 
      else 
         if not has(f0,x) and not has(f2,x) then 
            RETURN(FAIL); 
         else 
            RETURN(f0,f1,f2); 
         fi; 
      fi; 
   else #check for f1 missing 
      if patmatch(RHS,f0::anything+f2::anything*y(x)^2,'la') then 
         assign(la); 
         if has(f0,y(x)) or has(f2,y(x)) then RETURN(FAIL); fi; 
         if not has(f0,x) and not has(f2,x) then RETURN(FAIL); fi; 
         RETURN(f0,0,f2); 
      else 
         RETURN(FAIL); 
      fi; 
   fi; 
 
end proc:
 

Example usage

ode:=diff(y(x),x)=f0(x)+f1*y(x)+f2*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                         f0(x), f1, f2 
                           [_Riccati] 
 
ode:=diff(y(x),x)=f0+f1(x)*y(x)+f2*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                         f0, f1(x), f2 
                           [_Riccati] 
 
ode:=diff(y(x),x)=f0(x)+f1(x)*y(x)+f2*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                        f0(x), f1(x), f2 
                           [_Riccati] 
 
ode:=diff(y(x),x)=f0(x)+f1(x)*y(x)+f2(x)*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                      f0(x), f1(x), f2(x) 
                           [_Riccati] 
 
ode:=diff(y(x),x)=f0(x)+f2(x)*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                        f0(x), 0, f2(x) 
                           [_Riccati] 
 
ode:=diff(y(x),x)=x+f2(x)*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                          x, 0, f2(x) 
                           [_Riccati] 
 
ode:=diff(y(x),x)=x+f2*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                              FAIL 
                     [[_Riccati, _special]] 
 
ode:=diff(y(x),x)=1/x+y(x)+y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                            1 
                            -, 1, 1 
                            x 
                     [_rational, _Riccati] 
 
ode:=diff(y(x),x)=1/x+y(x)+x*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                            1 
                            -, 1, x 
                            x 
                     [_rational, _Riccati] 
 
ode:=diff(y(x),x)=x*y(x)+c*y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                              FAIL 
                          [_Bernoulli] 
 
ode:=diff(y(x),x)=x-1+y(x)^2: 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
                          -1 + x, 0, 1 
                           [_Riccati] 
 
ode:=diff(y(x),x)=(3+9*x+8*y(x))^(2): #this onde needs the collect 
general_riccati_parse(ode,y(x)); 
DETools:-odeadvisor(ode); 
 
              81*x^2 + 54*x + 9, 144*x + 48, 64 
              [[_homogeneous, class C], _Riccati]
 

1.3 Detect ode of form \(y'=(a + b x + c y(x))^n\)

Where \(n\) can not be \(1\). \(a\) can be missing but not \(b,c\). And \(a,b,c\) are scalars.

The parsing routing returns either FAIL or \(a,b,c,b\) if pattern is matched.

homog_c_parse:=proc(ode::`=`,func::function(name),$) 
 
local RHS; 
local y:=op(0,func); 
local x:=op(1,func); 
 
local la,a,b,c,n,p,the_power; 
 
   try 
      RHS:=timelimit(30,[solve(ode,diff(y(x),x))]); 
      if nops(RHS)<>1 then RETURN(FAIL); fi; 
      RHS:=simplify(RHS[1]); 
   catch: 
      RETURN(FAIL); 
   end try; 
 
   if patmatch(RHS,(p::anything)^(the_power::anything),'la') then 
      assign(la); 
      if the_power=1 then 
         RETURN(FAIL); 
      fi; 
      if patmatch(p,a::anything+b::anything*x+c::anything*y(x),'la') then 
         assign(la); 
         if has(a,x) or has(a,y(x)) then RETURN(FAIL); fi; 
         if has(b,x) or has(b,y(x)) then RETURN(FAIL); fi; 
         if has(c,x) or has(c,y(x)) then RETURN(FAIL); fi; 
         RETURN(a,b,c,the_power); 
      else 
         if patmatch(p,b::anything*x+c::anything*y(x),'la') then 
            assign(la); 
            if has(b,x) or has(b,y(x)) then RETURN(FAIL); fi; 
            if has(c,x) or has(c,y(x)) then RETURN(FAIL); fi; 
            RETURN(0,b,c,the_power); 
         else 
            RETURN(FAIL); 
         fi; 
      fi; 
   else 
      RETURN(FAIL); 
   fi; 
end proc:
 

Examples usages

ode:=diff(y(x),x)=(3+9*x+8*y(x))^(1/2): 
homog_c_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
                                    1 
                           3, 9, 8, - 
                                    2 
             [[_homogeneous, class C], _dAlembert] 
 
ode:=diff(y(x),x)=(3+9*x+8*y(x))^(2): 
homog_c_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                           3, 9, 8, 2 
              [[_homogeneous, class C], _Riccati] 
 
ode:=(x+y(x))*diff(y(x),x)=1: 
homog_c_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
                          0, 1, 1, -1 
     [[_homogeneous, class C], [_Abel, 2nd type, class C], _dAlembert] 
 
ode:=diff(y(x),x)=sqrt(x+y(x)+1): 
homog_c_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
                                    1 
                           1, 1, 1, - 
                                    2 
             [[_homogeneous, class C], _dAlembert] 
 
ode:=diff(y(x),x)=1/(x+y(x)+1): 
homog_c_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                          1, 1, 1, -1 
    [[_homogeneous, class C], [_Abel, 2nd type, class C], _dAlembert] 
 
ode:=diff(y(x),x)=1/(x+y(x)+sin(x)): 
homog_c_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
 
                              FAIL 
                  [[_Abel, 2nd type, class C]] 
 
ode:=diff(y(x),x)=(x+y(x)^2)^(2/3): 
homog_c_parse(ode,y(x)); 
DEtools:-odeadvisor(ode); 
                              FAIL 
                          [y=_G(x,y')]
 

1.4 pattern example 1

Given list \(3,4,x,x^2,x^3\), find those elements of form \(x^n\) where \(n\) is anything other than \(1\).

In Maple

L:=[3,4,x,x^2,x^3]; 
map(X->`if`(patmatch(X,x^n::nonunit(anything)),X,NULL),L) 
 
     [x^2, x^3]
 

The above can also be written in the long form

restart; 
 
L:=[3,4,x,x^2,x^3]; 
 
map(proc(X) 
    if patmatch(X,x^n::nonunit(anything)) then 
       X; 
    else 
      NULL; 
    fi; 
    end proc,L) 
 
 
     [x^2, x^3]
 

In Mathematica

Cases[{3, 4, x, x^2, x^3}, x^_] 
 
          {x^2, x^3}
 

1.5 pattern example 2

Given list \(3,4,x,x^2,x^3\), find those elements of form \(x^n\) where \(n\) is now allowed to be 1. In Maple

L:=[3,4,x,x^2,x^3]; 
map(X->`if`(patmatch(X,x^n::anything),X,NULL),L) 
 
     [x, x^2, x^3]
 

In Mathematica

Cases[{3, 4, x, x^2, x^3}, x^_.] 
 
          {x,x^2,x^3}
 

1.6 pattern example 3

Given list \(3,4,x,x^2,x^3\), return list of exponents of \(x\), other than \(1\).

In Maple

L:=[3,4,x,x^2,x^3]; 
f:=proc(X::anything,x::symbol) 
   local la,n; 
   if patmatch(X,x^n::nonunit(anything),'la') then 
       eval(n,la); 
    else 
       NULL; 
    fi; 
end proc; 
 
map(X->f(X,x),L) 
 
   [2, 3]
 

Another option is to use inlined if, like this

restart; 
L:=[3,4,x,x^2,x^3]; 
map(proc(X) local la,n; 
 
    if  patmatch(X,x^n::nonunit(anything),'la') then 
        eval(n,la); 
    else 
        NULL; 
    fi; 
    end proc, L); 
 
 
    [2, 3]
 

In Mathematica

Cases[{3, 4, x, x^2, x^3}, x^n_ -> n] 
         {2, 3}
 

1.7 pattern example 4

Gives list {f(a,a),f(a,b),f(c,d),f(b,b)} return {g(a),f(a,b),f(c,d),g(b)} where only function that takes two arguments which are the same is replaced by \(g(x)\) where \(x\) here is the argument in the original list.

In Maple

restart; 
L:={f(a,a),f(a,b),f(c,d),f(b,b)}; 
map(X->[unassign('x'),`if`(patmatch(X,f(x::anything,x::anything),'la'),[assign(la),g(x)][],X)][],L) 
 
                 {f(a, b), f(c, d), g(a), g(b)}
 

Or using the long form of map, which is more clear, even though the code is longer

restart; 
L:={f(a,a),f(a,b),f(c,d),f(b,b)}; 
 
map(proc(X) local la; 
    if  patmatch(X,f('x'::anything,'x'::anything),'la') then 
        g(eval('x',la)); 
    else 
        X; 
    fi; 
    end proc, L 
); 
 
         {f(a, b), f(c, d), g(a), g(b)}
 

In Mathematica

L = {f[a, a], f[a, b], f[c, d], f[b, b]} 
L /. f[x_, x_] -> g[x] 
 
       {g[a], f[a, b], f[c, d], g[b]}
 

1.8 pattern example 5

Given f(a)+f(b) transform it using pattern f(x::anything)->x^2 to obtain a^2+b^2

In Maple

expr:=f(a)+f(b); 
map( proc(X) local la,x; 
     if patmatch(X,f(x::anything),'la') then 
        eval(x,la)^2; 
     else 
        NULL; 
     fi; 
     end proc, expr); 
 
 
           a^2 + b^2
 

In Mathematica

f[a] + f[b] /. f[x_] -> x^2 
 
    a^2+b^2
 

1.9 pattern example 6

Given [1, x, x^2, x^3] write pattern to change all x^n::anything to r(n)

In Maple

L:=[1, x, x^2, x^3]; 
map( proc(X) local la,n; 
     if patmatch(X,x^n::'nonunit'(anything),'la') then 
        r(eval(n,la)); 
     else 
        X; 
     fi; 
     end proc, L); 
 
 
         [1, x, r(2), r(3)]
 

In Mathematica

{1, x, x^2, x^3} /. x^n_ -> r[n] 
 
   {1, x, r[2], r[3]}
 

1.10 pattern example 7

Given f(a + b) + f(a + c) + f(b + d) apply transformation f(a + x_) + f(c + y_) -> p(x, y)

Here to do not use map, since we want to apply pattern on the whole expression. In Maple

restart; 
expr:=f(a+b)+f(a+c)+f(b+d): 
 
if patmatch(expr,f(a+x::anything)+f(c+y::anything)+z::anything,'la') then 
   p(eval(x,la),eval(y,la))+eval(z,la); 
else 
   expr; 
fi; 
 
        p(b, a) + f(b + d)
 

In Mathematica

f[a+b]+f[a+c]+f[b+d]/. f[a+x_]+f[c+y_]->p[x,y] 
 
     f[b+d]+p[b,a]
 

1.11 pattern example 8

Write pattern to change f(a^b) to p(a^b,b)

In Maple

restart; 
expr:=f(a^b); 
 
if patmatch(expr,f( (a::anything)^b::anything ),'la') then 
   print(la); 
   p( eval(a,la)^eval(b,la) , eval(b,la) ); 
else 
   expr; 
fi; 
 
 
     p(a^b, b)
 

In Mathematica

f[a^b] /. f[x : _^n_] -> p[x, n] 
 
     p[a^b,b]
 

1.12 pattern example 9

Write pattern to select from list [3,-4,5,-2] only the numbers that are negative.

In Maple, we use the form patmatch(X, conditional(patttern,condition))

restart; 
L:=[3,-4,5,-2]; 
map( proc(X) local la; 
     if patmatch(X, conditional(n::integer,n<0),'la') then 
        eval(n,la); 
     else 
        NULL; 
     fi; 
     end proc, L); 
 
 
    [-4, -2]
 

In Mathematica

Cases[{3, -4, 5, -2}, x_ /; x < 0] 
 
    {-4,-2}
 

1.13 pattern example 10

Write pattern to select from list [z(1, 1), z(-1, 1), z(-2, 2)] only those with first argument which is negative.

In Maple, we use the form patmatch(X, conditional(patttern,condition))

restart; 
L:=[z(1, 1), z(-1, 1), z(-2, 2)]; 
map( proc(X) local la,a,b; 
     if patmatch(X, conditional(z(a::integer,b::integer),a<0),'la') then 
        z(eval(a,la),eval(b,la)); 
     else 
        NULL; 
     fi; 
     end proc, L 
    ); 
 
 
         [z(-1, 1), z(-2, 2)]
 

In Mathematica

Cases[{z[1, 1], z[-1, 1], z[-2, 2]}, z[x_ /; x < 0, y_]] 
 
    {z[-1,1],z[-2,2]}
 

1.14 pattern example 11

Write pattern to select from list 1+a,2+a,-3+a] only those that have negative number added to \(a\) and output \(p(x)\) where \(x\) is that number.

In Maple, we use the form patmatch(X, conditional(patttern,condition))

L:=[1+a,2+a,-3+a]; 
map( proc(X) local la,x; 
     if patmatch(X, conditional(a+x::integer,x<0),'la') then 
        p(eval(x,la)); 
     else 
        X; 
     fi; 
     end proc, L 
    ); 
 
 
       [1 + a, 2 + a, p(-3)]
                                                                                    
                                                                                    
 

In Mathematica

{1+a,2+a,-3+a}/. (x_/;x<0)+a->p[x] 
 
   {1 + a, 2 + a, p[-3]}
 

1.15 pattern example 12

Use pattern to square only numbers in a list.

L:=[2.3,4,7/8,a,b]; 
map( proc(X) local la,x; 
     if patmatch(X, x::numeric,'la') then 
        eval(x,la)^2; 
     else 
        X; 
     fi; 
     end proc, L 
    ); 
 
       [5.29, 16, 49/64, a, b]
 

In Mathematica

{2.3, 4, 7/8, a, b} /. (x_ /; NumberQ[x]) -> x^2 
 
   {5.29,16,49/64,a,b}
 

1.16 pattern example 13

Use pattern to convert p(4.5) + p(3/2) + p(u) to 22.5 + p(u) by squaring and adding arguments of those function which has its argument numeric.

p:=x->`if`(x::numeric,x^2,x); 
p(4.5) + p(3/2) + p(u); 
 
 
      22.50000000 + u
 

In Mathematica

p[x_?NumberQ] := x^2 
p[4.5] + p[3/2] + p[u] 
 
   22.5 + p[u]
 

1.17 pattern example 14

Write pattern to pick all elements from list which are not integers.

L:=[a, b, 0, 1, 2, x, y]: 
map( proc(X) local la,x; 
     if patmatch(X, conditional( x::anything, not _type(x,integer) ),'la') then 
        eval(x,la); 
     else 
        NULL; 
     fi; 
     end proc, L 
    ); 
 
     [a, b, x, y]
 

This can also be done without pattern matching like this

select(not type,L,integer) 
 
      [a, b, x, y]
 

In Mathematica

Cases[{a, b, 0, 1, 2, x, y}, Except[_Integer]] 
 
   {a, b, x, y}
 

1.18 pattern example 15

Replace variable \(x\) in expression with a value \(1\).

L:=[x, x^2,y,z, sin(x), exp( tan(x) )]: 
 
f:=proc(X::anything,x::symbol) 
    local la,y; 
 
    if patmatch(X, conditional( y::anything, _has(y,x) ),'la') then 
        eval(y,la); 
        eval(%,x=1); 
     else 
        X; 
     fi; 
end proc; 
 
map(X->f(X,x),L); 
 
 
     [1, 1, y, z, sin(1), exp(tan(1))]
 

Actually, we do not need patmatch for this, but the above is just an exercise. This can be done in one line in Maple as follows

L:=[x, x^2,y,z, sin(x), exp( tan(x) )]: 
map(X->eval(X,x=1),L) 
 
   [1, 1, y, z, sin(1), exp(tan(1))]
 

In Mathematica

L={x, x^2,y,z, Sin[x], Exp[Tan[x]]} 
L/.x->1 
 
   {1,1,y,z,Sin[1],Exp[Tan[1]]}
 

1.19 pattern example 16

Replace variable \(x\) in expression with a list.

L:=[x, x^2,y,z]: 
 
f:=proc(X::anything,x::symbol) 
    local la,y; 
 
    if patmatch(X, conditional( y::anything, _has(y,x) ),'la') then 
        eval(y,la); 
        eval(%,x={a,b}); 
     else 
        X; 
     fi; 
end proc; 
 
map(X->f(X,x),L); 
 
 
     [{a, b}, {a, b}^2, y, z]
 

Actually, we do not need patmatch for this, but the above is just an exercise. This can be done in one line in Maple as follows

L:=[x, x^2,y,z]: 
map(X->eval(X,x={a,b}),L) 
 
   [{a, b}, {a, b}^2, y, z]
 

In Mathematica

{x, x^2, y, z} /. x -> {a, b} 
 
   {{a, b}, {a^2, b^2}, y, z}
 

1.20 pattern example 17

Replace \(sin\) by \(cos\)

f:=proc(X::anything) 
    local la,x; 
 
    if patmatch(X, conditional( x::anything, _has(x,sin) ),'la') then 
        eval(x,la); 
        eval(%,sin=cos); 
     else 
        X; 
     fi; 
end proc; 
 
L:=[sin(x), cos(x)+sin(2*x),tan(x)]: 
map(X->f(X), L); 
 
 
    [cos(x), cos(x) + cos(2*x), tan(x)]
 

Actually, we do not need patmatch for this, but the above is just an exercise. This can be done in one line in Maple as follows

L:=[sin(x), cos(x)+sin(2*x),tan(x)]: 
map(X->eval(X,sin=cos), L) 
 
 
    [cos(x), cos(x) + cos(2*x), tan(x)]
 

In Mathematica

{Sin[x], Cos[x] + Sin[2*x], Tan[x]} /. Sin -> Cos 
 
   {Cos[x], Cos[x] + Cos[2 x], Tan[x]}
 

1.21 pattern example 18

Use pattern to replace \(x^n\) by \(f(n)\)

restart; 
expr:=1 + x^2 + x^4; 
 
F:=proc(X::anything,x::symbol) 
    local la,y,n; 
    if patmatch(X, (y::anything)^(n::'nonunit'(anything)) ,'la') then 
        if eval(y,la)=1 then #bug in maple? 
           X; 
        else 
           f(eval(n,la)); 
        fi; 
     else 
        X; 
     fi; 
end proc; 
 
map(X->F(X,x), expr); 
 
 
    f(4) + f(2) + 1
 

In Mathematica

1 + x^2 + x^4 /. x^p_ :> f[p] 
 
   1 + f[2] + f[4]
 

1.22 pattern example 19

replaces a whole expression by default. In Maple, this is easier to do it without pattern, like this

restart; 
expr:=f(1, 2, z); 
e:=map(X->`if`(X::integer,"int",X),[op(expr)]); 
f(op(e)) 
 
    f("int", "int", z)
 

In Mathematica, a pattern works easier

Replace[f[1, 2, z], _Integer :> "int", {1}] 
 
   f["int", "int", z]
 

The main issue is that it is hard to match a squence in Maple. For example, in Mathematica this works

f[1, 2, z] /. f[x___] :> x 
 
        Sequence[1, 2, z]
 

But in Maple

expr:=f(1, 2, z); 
patmatch(expr, f(x::anything)) 
 
      false
 

So pattern matching does work to match sequence of arguments.