====================================================================
Kernel examples
====================================================================

A kernel is a symbolic function application (such as sin(x+ y)) 
or a symbol (such as x).  More precisely, a non-symbol
kernel over a set S is an operator applied to a given list of
arguments from S.  The operator has type BasicOperator
and the kernel object is usually part of an Expression object.

Kernels are created implicitly for you when you create expressions.

  x :: Expression Integer
    x
                         Type: Expression Integer

You can directly create a "symbol" kernel by using the kernel operation.

  kernel x
    x
                         Type: Kernel Expression Integer

This expression has two different kernels.

  sin(x) + cos(x)
    sin(x) + cos(x)
                         Type: Expression Integer

The operator kernels returns a list of the kernels in an object of
type Expression.

  kernels %
    [sin(x),cos(x)]
                         Type: List Kernel Expression Integer

This expression also has two different kernels.

  sin(x)**2 + sin(x) + cos(x)
          2
    sin(x)  + sin(x) + cos(x)
                         Type: Expression Integer

The sin(x) kernel is used twice.

  kernels %
    [sin(x),cos(x)]
                         Type: List Kernel Expression Integer

An expression need not contain any kernels.

  kernels(1 :: Expression Integer)
    []
                         Type: List Kernel Expression Integer

If one or more kernels are present, one of them is designated the main
kernel.

  mainKernel(cos(x) + tan(x))
    tan(x)
                         Type: Union(Kernel Expression Integer,...)

Kernels can be nested. Use height  to determine the nesting depth.

  height kernel x
    1
                         Type: PositiveInteger

This has height 2 because the x has height 1 and then we apply an
operator to that.

  height mainKernel(sin x)
    2
                         Type: PositiveInteger

  height mainKernel(sin cos x)
    3
                         Type: PositiveInteger

  height mainKernel(sin cos (tan x + sin x))
    4
                         Type: PositiveInteger

Use the operator operation to extract the operator component of the
kernel.  The operator has type BasicOperator.

  operator mainKernel(sin cos (tan x + sin x))
    sin
                         Type: BasicOperator

Use the name operation to extract the name of the operator component
of the kernel.  The name has type Symbol.  This is really just a
shortcut for a two-step process of extracting the operator and then
calling name on the operator.

  name mainKernel(sin cos (tan x + sin x))
    sin
                         Type: Symbol

FriCAS knows about functions such as sin, cos and so on and can make
kernels and then expressions using them.  To create a kernel and
expression using an arbitrary operator, use operator.

Now f can be used to create symbolic function applications.

  f := operator 'f 
    f
                        Type: BasicOperator

  e := f(x, y, 10) 
    f(x,y,10)
                        Type: Expression Integer

Use the is? operation to learn if the operator component of a kernel
is equal to a given operator.

  is?(e, f) 
    true
                        Type: Boolean

You can also use a symbol or a string as the second argument to is?.

  is?(e, 'f)
    true
                        Type: Boolean

Use the argument operation to get a list containing the argument
component of a kernel.

  argument mainKernel e
    [x,y,10]
                        Type: List Expression Integer

Conceptually, an object of type Expression can be thought of a
quotient of multivariate polynomials, where the "variables" are
kernels.  The arguments of the kernels are again expressions and so
the structure recurses.  See Expression for examples of using kernels
to take apart expression objects.

See Also:
o )help Expression
o )help BasicOperator
o )show Kernel

