@maxbanados By "that whole family of commands", I mean **applyrule**, **define**, **definemore**, **match**, **patmatch**, and **typematch**. Maple's **type** subsystem has a very rich and highly logical syntax easily capable of expressing types of arbitrary complexity, with subtypes nested arbitrarily deep (even recursively). The commands listed above use a *variation *of a __miniscule__ subset of that syntax. That variation is incredibly frustrating and illogical (and even sometimes self-contradictory) to me. The command **compiletable **also uses that variation; however, I didn't include it in "that family" because it has important functionality that'd be elsewise difficult to duplicate. Also, it appears to me (although I've only checked superficially) that there's been no significant update to these commands in over 20 years. I'd guess that whoever developed these moved on from Maple.

*The* premier command for extracting subexpressions based on their type is now (and always has been) **indets**.

Regarding integrals with external coefficients: If you can tell me how you want to handle these special cases, I can advise further:

**2*Int(...)*Int(...)**
**2*x*Int(f(x), x) #indefinite**
**2*x*Int(f(x), x= a..b) #definite**
**2*Int(...) / Int(...)**

Regarding deconstruction: Maple's type system is great, one of the really powerful parts of the language. However, often we can assume that an expression is syntactically correct (so, some other syntax checker has already done the type work). Then the deconstruction can use the simpler commands **op**, **lhs**, **rhs**, etc. Here's an example:

**IntDecon:= proc(J::specfunc(Int))
local v:= op(2,J);
Record(
"operator"::name= op(0,J),
"integrand"::algebraic= op(1,J),
"intvars"::list(name)=
`if`(v::list(name= range), lhs~(v), [v]),
"lowerbounds"::list(algebraic)=
`if`(v::name, [], (lhs@rhs)~(`if`(v::list, v, [v]))),
"upperbounds"::list(algebraic)=
`if`(v::name, [], (rhs@@2)~(`if`(v::list, v, [v]))),
"options"::list({name, name= anything})= [op](3.., J)
)
end proc
:
I1:= Int(x*y, [x= -1..1, y= -2..2], numeric):
I1d:= IntDecon(I1);**
I1d := Record(operator::name = Int, integrand::algebraic = x y,
intvars::(list(name)) = [x, y],
lowerbounds::(list(algebraic)) = [-1, -2],
upperbounds::(list(algebraic)) = [1, 2],
`options`::(list({name, name = anything})) = [numeric])
**I1d:-intvars;**
[x, y]

Regarding **evalb** and **Categorize**: No, I think that **Categorize** is a great command. And recall that the problem in your Question has nothing to do with **typematch** either! Please post that example.