#
#--> gdegree(a:algebraic,x:{name,list(name),set(name)})
#
# gdegree(a,x) ==> degree of a in x
# gdegree(a,{x1,x2,...,xn}) ==> total degree in x1,x2,...,xn
# gdegree(a) ==> total degree in all variables
#
# This is an example of how to write a Maple procedure which
# walks through a Maple expression recursively.
#
# Author: MBM June/92
#

gdegree := proc(p) local t,v;
    v := args[2..nargs];
    if type(p,constant) then 0 # Note, includes symbolic constants e.g. Pi
    elif type(p,name) then
	if nargs=1 then 1
	elif type(v,{set,list}) then if member(p,v) then 1 else 0 fi
	else if p=v then 1 else 0 fi
	fi
    elif type(p,`*`) then convert([seq(gdegree(t,v), t=p)], `+`)
    elif type(p,`^`) then gdegree(op(1,p),v)*op(2,p)
    elif type(p,`+`) then max(seq(gdegree(t,v),t=p))
    elif nargs=1 or has(p,v) then ERROR(`unable to compute degree`)
    else 0
    fi
end:

`help/text/gdegree` := TEXT(
`   `,
`FUNCTION: gdegree - generalized degree function`,
`      `,
`CALLING SEQUENCE: gdegree(p); or gdegree(p,x);`,
`      `,
`PARAMETERS: p - a algebraic expression`,
`            x - a name or a list or set of names`,
`   `,
`SYNOPSIS:   `,
`   `,
`- The call gdegree(a,x) computes the degree of a in x`,
`- The call gdegree(a,{x1,...,xn}) computes the total degree in x1,...,xn`,
`- The call gdegree(a); computes total degree in all variables given by indets`,
`   `,
`- The degree function in Maple similarly computes the degree of a polynomial`,
`  but is restricted to integral powers.  Both positive and negative integers`,
`  are allowed but fractional, and general symbolic exponents are not.`,
`  E.g. degree(x^2+y^3,x); ==> 2  but  degree(x^n+y^m,x); ==> FAIL`,
`  The gdegree function generalizes from integer exponents to rational`,
`  exponents and symbolic exponents, as illustrated by the examples.`,
`   `,
`- This routine is intended primarilly to serve as an example of how to write`,
`  programs in Maple that compute with Maple algebraic expressions or formule.`,
`   `,
`EXAMPLES:   `,
`   `,
`> gdegree( x^(2/3)+x^(3/2), x );`,
`   `,
`                                      3/2`,
`> gdegree( x^a+x^2+x, x );`,
`   `,
`                                   max(a, 2)`,
`   `,
`> gdegree( x^a*y+x^b/y, {x,y} );`,
`   `,
`                               max(a + 1, b - 1)`
):

# save `gdegree.m`;
# quit
