ASFunctions.pas

File name
C:\Users\Andreas Rejbrand\Documents\Dev\AlgoSim\ASFunctions.pas
Date exported
Time exported
Formatting processor
TPascalFormattingProcessor
unit ASFunctions;

{ **************************************************************************** }
{ Rejbrand AlgoSim Kernel Functions                                            }
{ Copyright © 2018-2022 Andreas Rejbrand                                       }
{ https://english.rejbrand.se/                                                 }
{ **************************************************************************** }

{$WARN SYMBOL_PLATFORM OFF}
{$WARN DUPLICATE_CTOR_DTOR OFF}

interface

uses
  SysUtils, Types, Classes, Character, ASNum, ASTree, ASKernelDefs, ASObjects,
  ASObjStore, ASStructs, ASExpression, ASFcnMgr, Generics.Defaults,
  Generics.Collections, ASExecutionContext, Graphics, UITypes, GenHelpers,
  ASKernel, DoublePoint;

type
  [&Function('exprl')]
  [&Category(fcSystem)]
  FCN_ListExprNode = class(TASListExprNode);

  [&Function('identity')]
  [&Category(fcGeneral, fcMath)]
  FCN_Identity = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('add')]
  [&Category(fcGeneral, fcMath, fcStrings, fcSounds)]
  FCN_Add = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('subtract')]
  [&Category(fcGeneral, fcMath, fcSounds)]
  FCN_Subtract = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('negative')]
  [&Category(fcGeneral, fcMath)]
  FCN_UnaryMinus = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('multiply')]
  [&Category(fcGeneral, fcMath, fcStrings, fcSounds)]
  FCN_Multiply = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('InnerProduct')]
  [&Category(fcMath)]
  FCN_InnerProduct = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('divide')]
  [&Category(fcGeneral, fcMath)]
  FCN_Divide = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('power')]
  [&Category(fcMath)]
  FCN_Power = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('cross')]
  [&Category(fcMath)]
  FCN_Cross = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CrossProduct')]
  [&Category(fcMath)]
  FCN_CrossProduct = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('angle', '∠')]
  [&Category(fcMath)]
  FCN_Angle = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('factorial')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_Factorial = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('abs')]
  [&Category(fcMath)]
  FCN_Absolute = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ConjugateTranspose')]
  [&Category(fcMath)]
  FCN_ConjugateTranspose = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('transpose')]
  [&Category(fcMath)]
  FCN_Transpose = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('arg')]
  [&Category(fcMath)]
  FCN_Argument = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Re')]
  [&Category(fcMath)]
  FCN_RealPart = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Im')]
  [&Category(fcMath)]
  FCN_ImaginaryPart = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('sqrt')]
  [&Category(fcMath)]
  FCN_Sqrt = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('degrees')]
  [&Category(fcMath)]
  FCN_Deg = class(TASSimpleFunction)
  strict private
    class var PiDiv180: TAlgosimNumber;
    class constructor ClassCreate;
    class destructor ClassDestroy;
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('percent')]
  [&Category(fcMath)]
  FCN_Percent = class(TASSimpleFunction)
  strict private
    class var OneHundredth: TAlgosimNumber;
    class constructor ClassCreate;
    class destructor ClassDestroy;
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('permille')]
  [&Category(fcMath)]
  FCN_Permille = class(TASSimpleFunction)
  strict private
    class var OneThousandth: TAlgosimNumber;
    class constructor ClassCreate;
    class destructor ClassDestroy;
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('square', 'sqr')]
  [&Category(fcMath)]
  FCN_Square = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('sin')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_sin = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('cos')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_cos = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('tan')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_tan = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('cot')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_cot = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('sec')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_sec = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('csc')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_csc = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('arcsin')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_arcsin = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('arccos')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_arccos = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('arctan')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_arctan = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('arccot')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_arccot = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('arcsec')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_arcsec = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('arccsc')]
  [&Category(fcMath, fcTrigonometry)]
  FCN_arccsc = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('sinh')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_sinh = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('cosh')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_cosh = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('tanh')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_tanh = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('coth')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_coth = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('sech')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_sech = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('csch')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_csch = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('arcsinh')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_arcsinh = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('arccosh')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_arccosh = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('arctanh')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_arctanh = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('arccoth')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_arccoth = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('arcsech')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_arcsech = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('arccsch')]
  [&Category(fcMath, fcHyperbolic)]
  FCN_arccsch = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('sinc')]
  [&Category(fcMath)]
  FCN_sinc = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('exp')]
  [&Category(fcMath)]
  FCN_exp = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('ln')]
  [&Category(fcMath)]
  FCN_ln = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('log')]
  [&Category(fcMath)]
  FCN_log = class(TASSimpleFunctionNumDom)
  public
    procedure InitNode; override;
  end;

  [&Function('floor')]
  [&Category(fcMath)]
  FCN_Floor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ceil')]
  [&Category(fcMath)]
  FCN_Ceil = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('round')]
  [&Category(fcMath)]
  FCN_Round = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('trunc')]
  [&Category(fcMath)]
  FCN_Trunc = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('frac')]
  [&Category(fcMath)]
  FCN_Frac = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('sgn')]
  [&Category(fcMath)]
  FCN_Sgn = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('mod')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_mod = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('lcm')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_lcm = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('gcd')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_gcd = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('combinations', 'binomial')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_combinations = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('permutations')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_permutations = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsPrime')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_IsPrime = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NextPrime')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_NextPrime = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('PrevPrime')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_PrevPrime = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('prime')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_NthPrime = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('PrimePi')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_PrimePi = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Fibonacci')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_Fibonacci = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Lucas')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_Lucas = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MöbiusMu')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_MöbiusMu = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Mertens')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_Mertens = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('coprime')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_AreCoprime = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Iverson')]
  [&Category(fcMath)]
  FCN_Iverson = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Kronecker')]
  [&Category(fcMath)]
  FCN_Kronecker = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LegendreSymbol')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_LegendreSymbol = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('JacobiSymbol')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_JacobiSymbol = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('KroneckerSymbol')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_KroneckerSymbol = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('totient')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_totient = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('cototient')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_cototient = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('PrimeFactors')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_PrimeFactors = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rad')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_Radical = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsSquareFree')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_IsSquareFree = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('factors')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_Factorize = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FactorizedExpression')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_FactorizedExpression = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('divisors')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_Divisors = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ContinuedFraction')]
  [&Category(fcMath)]
  FCN_ContinuedFraction = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToFraction')]
  [&Category(fcMath)]
  FCN_ToFraction = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToSymbolicForm')]
  [&Category(fcMath)]
  FCN_ToSymbolicForm = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('erf')]
  [&Category(fcMath)]
  FCN_erf = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('erfc')]
  [&Category(fcMath)]
  FCN_erfc = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('FresnelC')]
  [&Category(fcMath)]
  FCN_FresnelC = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('FresnelS')]
  [&Category(fcMath)]
  FCN_FresnelS = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('Si')]
  [&Category(fcMath)]
  FCN_Si = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('Ci')]
  [&Category(fcMath)]
  FCN_Ci = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('Bessel')]
  [&Category(fcMath)]
  FCN_Bessel = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Laguerre')]
  [&Category(fcMath)]
  FCN_Laguerre = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Hermite')]
  [&Category(fcMath)]
  FCN_Hermite = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Legendre')]
  [&Category(fcMath)]
  FCN_Legendre = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('gamma')]
  [&Category(fcMath)]
  FCN_GammaFunction = class(TASSimpleFunctionNum)
  public
    procedure InitNode; override;
  end;

  [&Function('Chebyshev')]
  [&Category(fcMath)]
  FCN_Chebyshev = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Bernstein')]
  [&Category(fcMath)]
  FCN_Bernstein = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('HarmonicNumber')]
  [&Category(fcMath)]
  FCN_HarmonicNumber = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('and')]
  [&Category(fcLogic)]
  FCN_And = class(TASFunction)
  protected
    procedure DoExecute; override;
    procedure DoBitwise;
  end;

  [&Function('or')]
  [&Category(fcLogic)]
  FCN_Or = class(TASFunction)
  protected
    procedure DoExecute; override;
    procedure DoBitwise;
  end;

  [&Function('not')]
  [&Category(fcLogic)]
  FCN_Not = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('xor')]
  [&Category(fcLogic)]
  FCN_Xor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('nand')]
  [&Category(fcLogic)]
  FCN_Nand = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('nor')]
  [&Category(fcLogic)]
  FCN_Nor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ImpliesRight')]
  [&Category(fcLogic)]
  FCN_ImpliesRight = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ImpliesLeft')]
  [&Category(fcLogic)]
  FCN_ImpliesLeft = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('equivalent')]
  [&Category(fcLogic)]
  FCN_Equivalent = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('equals')]
  [&Category(fcGeneral)]
  FCN_Equals = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NotEquals')]
  [&Category(fcGeneral)]
  FCN_NotEquals = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LessThan')]
  [&Category(fcMath)]
  FCN_LessThan = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LessThanOrEqualTo')]
  [&Category(fcMath)]
  FCN_LessThanOrEqualTo = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GreaterThan')]
  [&Category(fcMath)]
  FCN_GreaterThan = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GreaterThanOrEqualTo')]
  [&Category(fcMath)]
  FCN_GreaterThanOrEqualTo = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('dim')]
  [&Category(fcMath)]
  FCN_Dim = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('size')]
  [&Category(fcMath, fcTables, fcPixmaps)]
  FCN_Size = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('width')]
  [&Category(fcMath, fcTables, fcPixmaps)]
  FCN_Width = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('height')]
  [&Category(fcMath, fcTables, fcPixmaps)]
  FCN_Height = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('subscript')]
  [&Category(fcGeneral)]
  FCN_Subscript = class(TASFunction)
  strict private
    // An array (typically of integers) (when necessary) populated with copies
    // of the values of the child nodes to allow indices as direct children. For
    // instance, A[1, 2] is effectively translated into A['(1, 2)], where
    // '(1, 2) is stored in this array. All code executed later on will only use
    // the array form of the indices.
    FEquivArray: TAlgosimArray;
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
    destructor Destroy; override;
  end;

  FCN_AccessMember = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('norm')]
  [&Category(fcMath)]
  FCN_Norm = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NormSquared')]
  [&Category(fcMath)]
  FCN_NormSquared = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('normalized')]
  [&Category(fcMath)]
  FCN_Normalized = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('first')]
  [&Category(fcGeneral, fcLists, fcStrings)]
  FCN_First = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('last')]
  [&Category(fcGeneral, fcLists, fcStrings)]
  FCN_Last = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('part')]
  [&Category(fcGeneral, fcLists, fcStrings)]
  FCN_Part = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('range')]
  [&Category(fcGeneral, fcLists, fcStrings)]
  FCN_Range = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('sort')]
  [&Category(fcGeneral, fcLists)]
  FCN_Sort = class(TASSimpleFunction)
  private
    rcmp: IComparer<TASR>;
    ccmp: IComparer<TASC>;
    procedure ChooseComparer(const AStr: string);
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CustomSort')]
  [&Category(fcGeneral, fcLists)]
  FCN_CustomSort = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('shuffle')]
  [&Category(fcGeneral, fcLists, fcStrings, fcPixmaps)]
  FCN_Shuffle = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('reverse')]
  [&Category(fcGeneral, fcLists, fcStrings, fcSounds)]
  FCN_Reverse = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('unique', 'RemoveDuplicates')]
  [&Category(fcGeneral, fcLists)]
  FCN_Unique = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RemoveAdjacentDuplicates')]
  [&Category(fcGeneral, fcLists)]
  FCN_AdjUnique = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('frequencies')]
  [&Category(fcGeneral, fcLists)]
  FCN_Frequencies = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('collapse')]
  [&Category(fcLists)]
  FCN_CollapseSequences = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ZeroVector')]
  [&Category(fcMath)]
  FCN_ZeroVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ComplexZeroVector')]
  [&Category(fcMath)]
  FCN_ComplexZeroVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RandomVector')]
  [&Category(fcMath)]
  FCN_RandomVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RandomIntVector')]
  [&Category(fcMath)]
  FCN_RandomIntVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RandomSignedVector')]
  [&Category(fcMath)]
  FCN_RandomSignedVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('BasisVector')]
  [&Category(fcMath)]
  FCN_BasisVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SequenceVector')]
  [&Category(fcMath)]
  FCN_SequenceVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SequenceList')]
  [&Category(fcMath)]
  FCN_SequenceList = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  TIntervalFunction = class(TASSimpleFunction)
  protected
    OpenInterval: Boolean;
    procedure SimpleFunction; override;
  end;  

  [&Function('ClosedInterval', 'interval')]
  [&Category(fcMath)]
  FCN_ClosedInterval = class(TIntervalFunction)
  protected
    procedure InitNode; override;
  end;

  [&Function('OpenInterval')]
  [&Category(fcMath)]
  FCN_OpenInterval = class(TIntervalFunction)
  protected
    procedure InitNode; override;  
  end;  

  [&Function('random')]
  [&Category(fcGeneral)]
  FCN_Random = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('RandomInt')]
  [&Category(fcMath)]
  FCN_RandomInt = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RandomReal')]
  [&Category(fcMath)]
  FCN_RandomReal = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetRandomSeed')]
  [&Category(fcMath)]
  FCN_SetRandomSeed = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('randomize')]
  [&Category(fcGeneral)]
  FCN_Randomize = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  TASContainerFunction = class abstract(TASFunction)
  protected
    procedure fcn(AObject: TAlgosimObject); virtual; abstract;
    procedure DoExecute; override; final;
  end;

  [&Function('sum', '∑')]
  [&Category(fcMath)]
  FCN_Sum = class(TASContainerFunction)
  protected
    procedure fcn(AObject: TAlgosimObject); override;
  end;

  [&Function('product', '∏')]
  [&Category(fcMath)]
  FCN_Product = class(TASContainerFunction)
  protected
    procedure fcn(AObject: TAlgosimObject); override;
  end;

  [&Function('min')]
  [&Category(fcMath)]
  FCN_Min = class(TASContainerFunction)
  protected
    procedure fcn(AObject: TAlgosimObject); override;
  end;

  [&Function('max')]
  [&Category(fcMath)]
  FCN_Max = class(TASContainerFunction)
  protected
    procedure fcn(AObject: TAlgosimObject); override;
  end;

  [&Function('ArithmeticMean', 'mean', 'average')]
  [&Category(fcMath)]
  FCN_ArithmeticMean = class(TASContainerFunction)
  protected
    procedure fcn(AObject: TAlgosimObject); override;
  end;

  [&Function('GeometricMean')]
  [&Category(fcMath)]
  FCN_GeometricMean = class(TASContainerFunction)
  protected
    procedure fcn(AObject: TAlgosimObject); override;
  end;

  [&Function('HarmonicMean')]
  [&Category(fcMath)]
  FCN_HarmonicMean = class(TASContainerFunction)
  protected
    procedure fcn(AObject: TAlgosimObject); override;
  end;

  TASContainerPredicateFunction = class abstract(TASFunction)
  protected
    procedure fcn(AObject: TAlgosimObject; APred: TASOPredicate);
      virtual; abstract;
    procedure DoExecute; override;
  end;

  [&Function('count')]
  [&Category(fcGeneral, fcLists)]
  FCN_Count = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('contains')]
  [&Category(fcGeneral, fcLists)]
  FCN_Contains = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('exists', '∃')]
  [&Category(fcGeneral, fcLists)]
  FCN_Exists = class(TASContainerPredicateFunction)
  protected
    procedure fcn(AObject: TAlgosimObject;
      APred: TASOPredicate); override;
  end;

  [&Function('ExistsUnique')]
  [&Category(fcGeneral, fcLists)]
  FCN_ExistsUnique = class(TASContainerPredicateFunction)
  protected
    procedure fcn(AObject: TAlgosimObject;
      APred: TASOPredicate); override;
  end;

  [&Function('ForAll', '∀')]
  [&Category(fcGeneral, fcLists)]
  FCN_ForAll = class(TASContainerPredicateFunction)
  protected
    procedure fcn(AObject: TAlgosimObject;
      APred: TASOPredicate); override;
  end;

  [&Function('indices')]
  [&Category(fcGeneral, fcLists)]
  FCN_IndicesOf = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('filter')]
  [&Category(fcGeneral, fcLists)]
  FCN_Filter = class(TASContainerPredicateFunction)
  protected
    procedure fcn(AObject: TAlgosimObject;
      APred: TASOPredicate); override;
  end;

  [&Function('pick')]
  [&Category(fcGeneral, fcLists)]
  FCN_Pick = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('PickRecursive')]
  [&Category(fcGeneral, fcLists)]
  FCN_PickRecursive = class(TASContainerPredicateFunction)
  protected
    procedure fcn(AObject: TAlgosimObject;
      APred: TASOPredicate); override;
  end;

  [&Function('apply')]
  [&Category(fcGeneral, fcLists)]
  FCN_Apply = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ApplyIf')]
  [&Category(fcGeneral, fcLists)]
  FCN_ApplyIf = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReplaceAll')]
  [&Category(fcGeneral, fcLists)]
  FCN_ReplaceAll = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReplaceIf')]
  [&Category(fcGeneral, fcLists)]
  FCN_ReplaceIf = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReplaceEvery')]
  [&Category(fcGeneral, fcLists)]
  FCN_ReplaceEvery = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RemoveAll')]
  [&Category(fcGeneral, fcLists)]
  FCN_RemoveAll = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RemoveIf')]
  [&Category(fcGeneral, fcLists)]
  FCN_RemoveIf = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RealNumber')]
  [&Category(fcGeneral)]
  FCN_RealNumber = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ComplexNumber')]
  [&Category(fcGeneral)]
  FCN_ComplexNumber = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('number')]
  [&Category(fcGeneral)]
  FCN_Number = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('integer')]
  [&Category(fcGeneral)]
  FCN_Integer = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('string')]
  [&Category(fcGeneral)]
  FCN_String = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RealVector')]
  [&Category(fcGeneral)]
  FCN_RealVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ComplexVector')]
  [&Category(fcGeneral)]
  FCN_ComplexVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('vector')]
  [&Category(fcGeneral, fcMath)]
  FCN_Vector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RealMatrix')]
  [&Category(fcGeneral)]
  FCN_RealMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ComplexMatrix')]
  [&Category(fcGeneral)]
  FCN_ComplexMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('matrix')]
  [&Category(fcGeneral, fcMath)]
  FCN_Matrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('boolean')]
  [&Category(fcGeneral)]
  FCN_Boolean = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToList')]
  [&Category(fcGeneral)]
  FCN_ToList = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToSet')]
  [&Category(fcGeneral)]
  FCN_ToSet = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToTable')]
  [&Category(fcGeneral)]
  FCN_ToTable = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('BinaryData')]
  [&Category(fcGeneral)]
  FCN_BinaryData = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MatFromCols')]
  [&Category(fcGeneral, fcMath)]
  FCN_MatrixFromCols = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MatFromRows')]
  [&Category(fcGeneral, fcMath)]
  FCN_MatrixFromRows = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MatFromBlocks')]
  [&Category(fcGeneral, fcMath)]
  FCN_MatrixFromBlocks = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('list', '''')]
  [&Category(fcLists)]
  FCN_List = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('set')]
  [&Category(fcSets)]
  FCN_Set = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('union')]
  [&Category(fcSets)]
  FCN_Union = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('intersection')]
  [&Category(fcSets)]
  FCN_Intersection = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetDifference')]
  [&Category(fcSets)]
  FCN_SetDifference = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SymmetricDifference')]
  [&Category(fcSets)]
  FCN_SymDiff = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('complement')]
  [&Category(fcSets)]
  FCN_Complement = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ElementOf')]
  [&Category(fcSets)]
  FCN_ElementOf = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NotElementOf')]
  [&Category(fcSets)]
  FCN_NotElementOf = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ContainsAsElement')]
  [&Category(fcSets)]
  FCN_ContainsAsElement = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NotContainsAsElement')]
  [&Category(fcSets)]
  FCN_NotContainsAsElement = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('subset')]
  [&Category(fcSets)]
  FCN_Subset = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ProperSubset')]
  [&Category(fcSets)]
  FCN_ProperSubset = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('superset')]
  [&Category(fcSets)]
  FCN_Superset = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ProperSuperset')]
  [&Category(fcSets)]
  FCN_ProperSuperset = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('type')]
  [&Category(fcSystem)]
  FCN_TypeName = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('ClassData')]
  [&Category(fcSystem)]
  FCN_ClassTypeData = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('class')]
  [&Category(fcSystem)]
  FCN_ClassTypeName = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('HasComplexType')]
  [&Category(fcSystem)]
  FCN_HasComplexType = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('IsObjectContainer')]
  [&Category(fcSystem)]
  FCN_IsObjectContainer = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('IsValueContainer')]
  [&Category(fcSystem)]
  FCN_IsValueContainer = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('IsPlanarContainer')]
  [&Category(fcSystem)]
  FCN_IsPlanarContainer = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('IsOrderedContainer')]
  [&Category(fcSystem)]
  FCN_IsOrderedContainer = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('beep')]
  [&Category(fcSystem)]
  FCN_Beep = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('wait', 'sleep')]
  [&Category(fcSystem)]
  FCN_Wait = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TickCount')]
  [&Category(fcSystem)]
  FCN_GetTickCount = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Heaviside')]
  [&Category(fcMath)]
  FCN_Heaviside = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('ramp')]
  [&Category(fcMath)]
  FCN_Ramp = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('rect')]
  [&Category(fcMath)]
  FCN_Rect = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('tri')]
  [&Category(fcMath)]
  FCN_Tri = class(TASSimpleFunctionReal)
  public
    procedure InitNode; override;
  end;

  [&Function('property')]
  [&Category(fcSystem)]
  FCN_GetProperty = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('integrate', '∫')]
  [&Category(fcMath)]
  FCN_Integrate = class abstract(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('differentiate', 'diff')]
  [&Category(fcMath)]
  FCN_Differentiate = class abstract(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('length', 'cardinality', 'card')]
  [&Category(fcGeneral, fcLists, fcStrings, fcStructures, fcSets)]
  FCN_Length = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('StringPos')]
  [&Category(fcStrings)]
  FCN_Pos = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('StringContains')]
  [&Category(fcStrings)]
  FCN_StringContains = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('StringCount')]
  [&Category(fcStrings)]
  FCN_SubstringCount = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('StringIndices')]
  [&Category(fcStrings)]
  FCN_SubstringIndices = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('StringReplace')]
  [&Category(fcStrings)]
  FCN_StringReplace = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('split')]
  [&Category(fcStrings)]
  FCN_Split = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('join')]
  [&Category(fcStrings)]
  FCN_Join = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('UpperCase')]
  [&Category(fcStrings)]
  FCN_UpperCase = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LowerCase')]
  [&Category(fcStrings)]
  FCN_LowerCase = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('InvertCase')]
  [&Category(fcStrings)]
  FCN_InvertCase = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TitleCase')]
  [&Category(fcStrings)]
  FCN_TitleCase = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SentenceCase')]
  [&Category(fcStrings)]
  FCN_SentenceCase = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rot13')]
  [&Category(fcStrings)]
  FCN_ROT13 = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Caesar')]
  [&Category(fcStrings)]
  FCN_Caesar = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('VigenèreEncode')]
  [&Category(fcStrings)]
  FCN_Vigenère = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('VigenèreDecode')]
  [&Category(fcStrings)]
  FCN_VigenèreDecode = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('trim')]
  [&Category(fcStrings)]
  FCN_Trim = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TrimLeft')]
  [&Category(fcStrings)]
  FCN_TrimLeft = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TrimRight')]
  [&Category(fcStrings)]
  FCN_TrimRight = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('StringPad')]
  [&Category(fcStrings)]
  FCN_Pad = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('format')]
  [&Category(fcStrings)]
  FCN_Format = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('index')]
  [&Category(fcGeneral, fcLists, fcStructures)]
  FCN_IndexOf = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  TCharTestFunction = class abstract(TASSimpleFunction)
  protected
  type
    TChrTestFcn = function(C: char): Boolean;
  var
    fcn: TChrTestFcn;
    procedure SimpleFunction; override; final;
  end;

  [&Function('ChrIsLetter')]
  [&Category(fcStrings)]
  FCN_ChrIsLetter = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsDigit')]
  [&Category(fcStrings)]
  FCN_ChrIsDigit = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsLetterOrDigit')]
  [&Category(fcStrings)]
  FCN_ChrIsLetterOrDigit = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsNumber')]
  [&Category(fcStrings)]
  FCN_ChrIsNumber = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsPunctuation')]
  [&Category(fcStrings)]
  FCN_ChrIsPunctuation = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsSeparator')]
  [&Category(fcStrings)]
  FCN_ChrIsSeparator = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsWhitespace')]
  [&Category(fcStrings)]
  FCN_ChrIsWhitespace = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsUpperCase')]
  [&Category(fcStrings)]
  FCN_ChrIsUpperCase = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsLowerCase')]
  [&Category(fcStrings)]
  FCN_ChrIsLowerCase = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsSymbol')]
  [&Category(fcStrings)]
  FCN_ChrIsSymbol = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsASCII')]
  [&Category(fcStrings)]
  FCN_ChrIsASCII = class(TCharTestFunction)
  strict private
    class function IsASCII(C: char): Boolean; static; inline;
  public
    procedure InitNode; override;
  end;

  [&Function('ChrIsControl')]
  [&Category(fcStrings)]
  FCN_ChrIsControl = class(TCharTestFunction)
  public
    procedure InitNode; override;
  end;

  [&Function('ChrName')]
  [&Category(fcStrings)]
  FCN_ChrName = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ChrBlock')]
  [&Category(fcStrings)]
  FCN_ChrBlock = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ChrBlocks')]
  [&Category(fcStrings)]
  FCN_ListChrBlocks = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ChrBlockRange')]
  [&Category(fcStrings)]
  FCN_ChrBlockRange = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('chr')]
  [&Category(fcStrings)]
  FCN_Character = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ord')]
  [&Category(fcStrings)]
  FCN_ChrCode = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ChrNumVal')]
  [&Category(fcStrings)]
  FCN_ChrNumVal = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('odd')]
  [&Category(fcMath)]
  FCN_Odd = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('even')]
  [&Category(fcMath)]
  FCN_Even = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('date')]
  [&Category(fcDateTime)]
  FCN_Date = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('time')]
  [&Category(fcDateTime)]
  FCN_Time = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('now')]
  [&Category(fcDateTime)]
  FCN_Now = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('datetime')]
  [&Category(fcDateTime)]
  FCN_DateTime = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  TTimeOneParamFcn = class abstract(TASSimpleFunction)
  protected
    type
      TTimeOneParamFcn32 = function(const ADateTime: TDateTime; const AParam: Integer): TDateTime;
      TTimeOneParamFcn64 = function(const ADateTime: TDateTime; const AParam: Int64): TDateTime;
    var
      fcn32: TTimeOneParamFcn32;
      fcn64: TTimeOneParamFcn64;

    procedure SimpleFunction; override; final;
  end;

  [&Function('AddMilliseconds')]
  [&Category(fcDateTime)]
  FCN_AddMilliseconds = class(TTimeOneParamFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('AddSeconds')]
  [&Category(fcDateTime)]
  FCN_AddSeconds = class(TTimeOneParamFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('AddMinutes')]
  [&Category(fcDateTime)]
  FCN_AddMinutes = class(TTimeOneParamFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('AddHours')]
  [&Category(fcDateTime)]
  FCN_AddHours = class(TTimeOneParamFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('AddDays')]
  [&Category(fcDateTime)]
  FCN_AddDays = class(TTimeOneParamFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('AddWeeks')]
  [&Category(fcDateTime)]
  FCN_AddWeeks = class(TTimeOneParamFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('AddMonths')]
  [&Category(fcDateTime)]
  FCN_AddMonths = class(TTimeOneParamFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('AddYears')]
  [&Category(fcDateTime)]
  FCN_AddYears = class(TTimeOneParamFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('IsValidDate')]
  [&Category(fcDateTime)]
  FCN_DateValid = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsValidTime')]
  [&Category(fcDateTime)]
  FCN_TimeValid = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsValidDatetime')]
  [&Category(fcDateTime)]
  FCN_DateTimeValid = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  TTimeTimeDoubleFcn = class abstract(TASSimpleFunction)
  protected
    type
      _TTimeTimeDoubleFcn = function(const ATime1, ATime2: TDateTime): double;
    var
      fcn: _TTimeTimeDoubleFcn;

    procedure SimpleFunction; override; final;
  end;

  [&Function('MillisecondsBetween')]
  [&Category(fcDateTime)]
  FCN_MillisecondsBetween = class(TTimeTimeDoubleFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('SecondsBetween')]
  [&Category(fcDateTime)]
  FCN_SecondsBetween = class(TTimeTimeDoubleFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('MinutesBetween')]
  [&Category(fcDateTime)]
  FCN_MinutesBetween = class(TTimeTimeDoubleFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('HoursBetween')]
  [&Category(fcDateTime)]
  FCN_HoursBetween = class(TTimeTimeDoubleFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('DaysBetween')]
  [&Category(fcDateTime)]
  FCN_DaysBetween = class(TTimeTimeDoubleFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('WeeksBetween')]
  [&Category(fcDateTime)]
  FCN_WeeksBetween = class(TTimeTimeDoubleFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('MonthsBetween')]
  [&Category(fcDateTime)]
  FCN_MonthsBetween = class(TTimeTimeDoubleFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('YearsBetween')]
  [&Category(fcDateTime)]
  FCN_YearsBetween = class(TTimeTimeDoubleFcn)
  public
    procedure InitNode; override;
  end;

  TTimeIntFcn = class abstract(TASSimpleFunction)
  protected
    type
      TTimeIntFcn16 = function(const ADateTime: TDateTime): Word;
      TTimeIntFcn32 = function(const ADateTime: TDateTime): Cardinal;
      TTimeIntFcn64 = function(const ADateTime: TDateTime): Int64;
    var
      fcn16: TTimeIntFcn16;
      fcn32: TTimeIntFcn32;
      fcn64: TTimeIntFcn64;
      IntFmt: TFormatStyle;

    procedure SimpleFunction; override;
  end;

  [&Function('DayOfTheWeek')]
  [&Category(fcDateTime)]
  FCN_DayOfTheWeek = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('DayOfTheMonth')]
  [&Category(fcDateTime)]
  FCN_DayOfTheMonth = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('DayOfTheYear')]
  [&Category(fcDateTime)]
  FCN_DayOfTheYear = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('WeekOfTheYear')]
  [&Category(fcDateTime)]
  FCN_WeekOfTheYear = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('SecondOfTheDay')]
  [&Category(fcDateTime)]
  FCN_SecondOfTheDay = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('SecondOfTheWeek')]
  [&Category(fcDateTime)]
  FCN_SecondOfTheWeek = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('SecondOfTheMonth')]
  [&Category(fcDateTime)]
  FCN_SecondOfTheMonth = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('SecondOfTheYear')]
  [&Category(fcDateTime)]
  FCN_SecondOfTheYear = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('MillisecondOfTheDay')]
  [&Category(fcDateTime)]
  FCN_MillisecondOfTheDay = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('MillisecondOfTheWeek')]
  [&Category(fcDateTime)]
  FCN_MillisecondOfTheWeek = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('MillisecondOfTheMonth')]
  [&Category(fcDateTime)]
  FCN_MillisecondOfTheMonth = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('MillisecondOfTheYear')]
  [&Category(fcDateTime)]
  FCN_MillisecondOfTheYear = class(TTimeIntFcn)
  public
    procedure InitNode; override;
  end;

  [&Function('IsLeapYear')]
  [&Category(fcDateTime)]
  FCN_IsLeapYear = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DaysInYear')]
  [&Category(fcDateTime)]
  FCN_DaysInYear = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DaysInMonth')]
  [&Category(fcDateTime)]
  FCN_DaysInMonth = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('timestamp')]
  [&Category(fcDateTime)]
  FCN_Timestamp = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('today')]
  [&Category(fcDateTime)]
  FCN_Today = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('tomorrow')]
  [&Category(fcDateTime)]
  FCN_Tomorrow = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('yesterday')]
  [&Category(fcDateTime)]
  FCN_Yesterday = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TruncToMillisecond')]
  [&Category(fcDateTime)]
  FCN_TruncateToMillisecond = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TruncToSecond')]
  [&Category(fcDateTime)]
  FCN_TruncateToSecond = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TruncToMinute')]
  [&Category(fcDateTime)]
  FCN_TruncateToMinute = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TruncToHour')]
  [&Category(fcDateTime)]
  FCN_TruncateToHour = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TruncToDay')]
  [&Category(fcDateTime)]
  FCN_TruncateToDay = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TruncToMonth')]
  [&Category(fcDateTime)]
  FCN_TruncateToMonth = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TruncToYear')]
  [&Category(fcDateTime)]
  FCN_TruncateToYear = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NumDigits')]
  [&Category(fcSystem)]
  FCN_NumDigits = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('MinLength')]
  [&Category(fcSystem)]
  FCN_MinLength = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('NumberFormat')]
  [&Category(fcSystem)]
  FCN_NumberFormat = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('NumberBase')]
  [&Category(fcSystem)]
  FCN_NumberBase = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('FormatStyle')]
  [&Category(fcSystem)]
  FCN_FormatStyle = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('DigitGrouping')]
  [&Category(fcSystem)]
  FCN_DigitGrouping = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('PrettyExp')]
  [&Category(fcSystem)]
  FCN_PrettyExp = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('MaxLen')]
  [&Category(fcSystem)]
  FCN_MaxLen = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('SetNumDigits')]
  [&Category(fcSystem)]
  FCN_SetNumDigits = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetMinLength')]
  [&Category(fcSystem)]
  FCN_SetMinLength = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetNumberFormat')]
  [&Category(fcSystem)]
  FCN_SetNumberFormat = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetNumberBase')]
  [&Category(fcSystem)]
  FCN_SetNumberBase = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetFormatStyle')]
  [&Category(fcSystem)]
  FCN_SetFormatStyle = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetDigitGrouping')]
  [&Category(fcSystem)]
  FCN_SetDigitGrouping = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetPrettyExp')]
  [&Category(fcSystem)]
  FCN_SetPrettyExp = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetMaxLen')]
  [&Category(fcSystem)]
  FCN_SetMaxLen = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AsSingleLine')]
  [&Category(fcSystem)]
  FCN_AsSingleLine = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('InputForm')]
  [&Category(fcSystem)]
  FCN_InputForm = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('AsMultiLine')]
  [&Category(fcSystem)]
  FCN_AsMultiLine = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('SaveToFile', 'export')]
  [&Category(fcSystem)]
  FCN_SaveToFile = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('LoadFromFile')]
  [&Category(fcSystem)]
  FCN_LoadFromFile = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CopyToClipboard')]
  [&Category(fcSystem)]
  FCN_CopyToClipboard = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('flatten')]
  [&Category(fcLists)]
  FCN_Flatten = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('group')]
  [&Category(fcLists)]
  FCN_Group = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  TSymbolNameFcn = class(TASFunction)
  protected
    procedure DoExecute; override; final;
    procedure fcn(const ASymbolName: string); virtual; abstract;
  end;

  [&Function('variable')]
  [&Category(fcSystem)]
  FCN_Variable = class(TSymbolNameFcn)
  protected
    procedure fcn(const ASymbolName: string); override;
  end;

  [&Function('object')]
  [&Category(fcSystem)]
  FCN_Object = class(TSymbolNameFcn)
  protected
    procedure fcn(const ASymbolName: string); override;
  end;

  [&Function('metadata')]
  [&Category(fcSystem)]
  FCN_Metadata = class(TSymbolNameFcn)
  protected
    procedure fcn(const ASymbolName: string); override;
  end;

  [&Function('description')]
  [&Category(fcSystem)]
  FCN_Description = class(TSymbolNameFcn)
  protected
    procedure fcn(const ASymbolName: string); override;
  end;

  [&Function('delete')]
  [&Category(fcSystem)]
  FCN_Delete = class(TSymbolNameFcn)
  protected
    procedure fcn(const ASymbolName: string); override;
  end;

  [&Function('protect')]
  [&Category(fcSystem)]
  FCN_Protect = class(TSymbolNameFcn)
  protected
    procedure fcn(const ASymbolName: string); override;
  end;

  [&Function('unprotect')]
  [&Category(fcSystem)]
  FCN_Unprotect = class(TSymbolNameFcn)
  protected
    procedure fcn(const ASymbolName: string); override;
  end;

  [&Function('assign')]
  [&Category(fcSystem)]
  FCN_Assign = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('cls')]
  [&Category(fcSystem)]
  FCN_Cls = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('exit')]
  [&Category(fcSystem)]
  FCN_Exit = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('error', 'fail')]
  [&Category(fcSystem)]
  FCN_Fail = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('assert')]
  [&Category(fcSystem)]
  FCN_Assert = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('succeeded')]
  [&Category(fcSystem)]
  FCN_Succeeded = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('try')]
  [&Category(fcSystem)]
  FCN_Try = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('piecewise')]
  [&Category(fcMath)]
  FCN_Piecewise = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('MakeMember')]
  [&Category(fcStructures)]
  FCN_MakeMember = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('struct', 'structure')]
  [&Category(fcStructures)]
  FCN_MakeStruct = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('system')]
  [&Category(fcSystem)]
  FCN_System = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RotLeft')]
  [&Category(fcGeneral)]
  FCN_RotLeft = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RotRight')]
  [&Category(fcGeneral)]
  FCN_RotRight = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('diag')]
  [&Category(fcMath)]
  FCN_Diag = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('row')]
  [&Category(fcGeneral, fcMath, fcTables)]
  FCN_Row = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('col')]
  [&Category(fcGeneral, fcMath, fcTables)]
  FCN_Col = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('rows')]
  [&Category(fcGeneral, fcMath, fcTables)]
  FCN_Rows = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('cols')]
  [&Category(fcGeneral, fcMath, fcTables)]
  FCN_Cols = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('MainDiagonal')]
  [&Category(fcMath)]
  FCN_MainDiagonal = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('superdiagonal')]
  [&Category(fcMath)]
  FCN_Superdiagonal = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('subdiagonal')]
  [&Category(fcMath)]
  FCN_Subdiagonal = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('antidiagonal')]
  [&Category(fcMath)]
  FCN_Antidiagonal = class(TASFunction)
  protected
    procedure DoExecute; override;
  public
    function BuildLValue(LValueData: TLValueData): Boolean; override;
    function LValuePart: Boolean; override;
  end;

  [&Function('ReplaceRow')]
  [&Category(fcMath)]
  FCN_ReplaceRow = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReplaceCol')]
  [&Category(fcMath)]
  FCN_ReplaceCol = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReplaceDiagonal')]
  [&Category(fcMath)]
  FCN_ReplaceDiagonal = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReplaceSuperdiagonal')]
  [&Category(fcMath)]
  FCN_ReplaceSuperdiagonal = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReplaceSubdiagonal')]
  [&Category(fcMath)]
  FCN_ReplaceSubdiagonal = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReplaceAntidiagonal')]
  [&Category(fcMath)]
  FCN_ReplaceAntidiagonal = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsRow')]
  [&Category(fcGeneral, fcMath, fcPixmaps, fcTables)]
  FCN_IsRow = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('IsCol')]
  [&Category(fcGeneral, fcMath, fcPixmaps, fcTables)]
  FCN_IsCol = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('IsSquare')]
  [&Category(fcGeneral, fcMath, fcPixmaps, fcTables)]
  FCN_IsSquare = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  TMatrixEpsilonFunction<T> = class abstract(TASFunction)
  strict protected
    type
      TEpsilonFcn = function(const Epsilon: Extended = 0): T of object;
    var
      rfcn, cfcn: TEpsilonFcn;
      generic_result: T;
    class var
      _TRealMatrix: TRealMatrix; // only used in child classes to get method code ptrs in a semi-type-safe manner
      _TComplexMatrix: TComplexMatrix;
  protected
    procedure DoExecute; override;
  end;

  TMatrixQueryWithEpsilon = class abstract(TMatrixEpsilonFunction<Boolean>)
  protected
    procedure DoExecute; override;
  end;

  [&Function('IsIdentity')]
  [&Category(fcMath)]
  FCN_IsIdentity = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsZeroMatrix')]
  [&Category(fcMath)]
  FCN_IsZeroMatrix = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsDiagonal')]
  [&Category(fcMath)]
  FCN_IsDiagonal = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsAntidiagonal')]
  [&Category(fcMath)]
  FCN_IsAntiDiagonal = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsReversal')]
  [&Category(fcMath)]
  FCN_IsReversal = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsUpperTriangular')]
  [&Category(fcMath)]
  FCN_IsUpperTriangular = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsLowerTriangular')]
  [&Category(fcMath)]
  FCN_IsLowerTriangular = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsTriangular')]
  [&Category(fcMath)]
  FCN_IsTriangular = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsRowEchelonForm')]
  [&Category(fcMath)]
  FCN_IsRowEchelonForm = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsReducedRowEchelonForm')]
  [&Category(fcMath)]
  FCN_IsReducedRowEchelonForm = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsScalar')]
  [&Category(fcMath)]
  FCN_IsScalar = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsSymmetric')]
  [&Category(fcMath)]
  FCN_IsSymmetric = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsSkewSymmetric')]
  [&Category(fcMath)]
  FCN_IsSkewSymmetric = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsHermitian', 'IsSelfAdjoint')]
  [&Category(fcMath)]
  FCN_IsHermitian = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsSkewHermitian')]
  [&Category(fcMath)]
  FCN_IsSkewHermitian = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsOrthogonal')]
  [&Category(fcMath)]
  FCN_IsOrthogonal = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsUnitary')]
  [&Category(fcMath)]
  FCN_IsUnitary = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsNormal')]
  [&Category(fcMath)]
  FCN_IsNormal = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsBinary')]
  [&Category(fcMath)]
  FCN_IsBinary = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsPermutation')]
  [&Category(fcMath)]
  FCN_IsPermutation = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsCirculant')]
  [&Category(fcMath)]
  FCN_IsCirculant = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsToeplitz')]
  [&Category(fcMath)]
  FCN_IsToeplitz = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsHankel')]
  [&Category(fcMath)]
  FCN_IsHankel = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsUpperHessenberg')]
  [&Category(fcMath)]
  FCN_IsUpperHessenberg = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsLowerHessenberg')]
  [&Category(fcMath)]
  FCN_IsLowerHessenberg = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsTridiagonal')]
  [&Category(fcMath)]
  FCN_IsTridiagonal = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsUpperBidiagonal')]
  [&Category(fcMath)]
  FCN_IsUpperBidiagonal = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsLowerBidiagonal')]
  [&Category(fcMath)]
  FCN_IsLowerBidiagonal = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsBidiagonal')]
  [&Category(fcMath)]
  FCN_IsBidiagonal = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsCentrosymmetric')]
  [&Category(fcMath)]
  FCN_IsCentrosymmetric = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsVandermonde')]
  [&Category(fcMath)]
  FCN_IsVandermonde = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsIdempotent')]
  [&Category(fcMath)]
  FCN_IsIdempotent = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsInvolution')]
  [&Category(fcMath)]
  FCN_IsInvolution = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsPositiveDefinite')]
  [&Category(fcMath)]
  FCN_IsPositiveDefinite = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsPositiveSemidefinite')]
  [&Category(fcMath)]
  FCN_IsPositiveSemidefinite = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsNegativeDefinite')]
  [&Category(fcMath)]
  FCN_IsNegativeDefinite = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsNegativeSemidefinite')]
  [&Category(fcMath)]
  FCN_IsNegativeSemidefinite = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsIndefinite')]
  [&Category(fcMath)]
  FCN_IsIndefinite = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  [&Function('IsNilpotent')]
  [&Category(fcMath)]
  FCN_IsNilpotent = class(TMatrixQueryWithEpsilon)
    procedure InitNode; override;
  end;

  TMatrixIntFcnWithEpsilon = class abstract(TMatrixEpsilonFunction<Integer>)
  protected
    procedure DoExecute; override;
  end;

  [&Function('NilpotencyIndex')]
  [&Category(fcMath)]
  FCN_NilpotencyIndex = class(TMatrixIntFcnWithEpsilon)
  protected
    procedure InitNode; override;
  end;

  TNumEntEpsilonFunction = class abstract(TASFunction)
  protected
    procedure fcn(AObj: TAlgosimNumericEntity; const AEps: TASR); virtual; abstract;
    procedure DoExecute; override; final;
  end;

  [&Function('IsPositive')]
  [&Category(fcMath)]
  FCN_IsPositive = class(TNumEntEpsilonFunction)
  protected
    procedure fcn(AObj: TAlgosimNumericEntity; const AEps: TASR); override;
  end;

  [&Function('IsNonNegative')]
  [&Category(fcMath)]
  FCN_IsNonNegative = class(TNumEntEpsilonFunction)
  protected
    procedure fcn(AObj: TAlgosimNumericEntity; const AEps: TASR); override;
  end;

  [&Function('IsNegative')]
  [&Category(fcMath)]
  FCN_IsNegative = class(TNumEntEpsilonFunction)
  protected
    procedure fcn(AObj: TAlgosimNumericEntity; const AEps: TASR); override;
  end;

  [&Function('IsNonPositive')]
  [&Category(fcMath)]
  FCN_IsNonPositive = class(TNumEntEpsilonFunction)
  protected
    procedure fcn(AObj: TAlgosimNumericEntity; const AEps: TASR); override;
  end;

  [&Function('IsZero')]
  [&Category(fcMath)]
  FCN_IsZero = class(TNumEntEpsilonFunction)
  protected
    procedure fcn(AObj: TAlgosimNumericEntity; const AEps: TASR); override;
  end;

  [&Function('IsNonZero')]
  [&Category(fcMath)]
  FCN_IsNonZero = class(TNumEntEpsilonFunction)
  protected
    procedure fcn(AObj: TAlgosimNumericEntity; const AEps: TASR); override;
  end;

  [&Function('PivotPos')]
  [&Category(fcMath)]
  FCN_PivotPos = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsZeroRow')]
  [&Category(fcMath)]
  FCN_IsZeroRow = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsEssentiallyZeroRow')]
  [&Category(fcMath)]
  FCN_IsEssentiallyZeroRow = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsDiagonallyDominant')]
  [&Category(fcMath)]
  FCN_IsDiagonallyDominant = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsStrictlyDiagonallyDominant')]
  [&Category(fcMath)]
  FCN_IsStrictlyDiagonallyDominant = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('commute')]
  [&Category(fcMath)]
  FCN_CommutesWith = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToLowerTriangular')]
  [&Category(fcMath)]
  FCN_ToLowerTriangular = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToUpperTriangular')]
  [&Category(fcMath)]
  FCN_ToUpperTriangular = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToUpperHessenberg')]
  [&Category(fcMath)]
  FCN_ToUpperHessenberg = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('HermitianSquare')]
  [&Category(fcMath)]
  FCN_HermitianSquare = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('modulus')]
  [&Category(fcMath)]
  FCN_Modulus = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('determinant', 'det')]
  [&Category(fcMath)]
  FCN_Determinant = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('tr')]
  [&Category(fcMath)]
  FCN_Trace = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('inv')]
  [&Category(fcMath)]
  FCN_Inverse = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rank')]
  [&Category(fcMath)]
  FCN_Rank = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('nullity')]
  [&Category(fcMath)]
  FCN_Nullity = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ConditionNumber')]
  [&Category(fcMath)]
  FCN_ConditionNumber = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsSingular')]
  [&Category(fcMath)]
  FCN_IsSingular = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DeletedAbsoluteRowSum')]
  [&Category(fcMath)]
  FCN_DeletedAbsoluteRowSum = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RowSwap')]
  [&Category(fcMath)]
  FCN_RowSwap = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RowScale')]
  [&Category(fcMath)]
  FCN_RowScale = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RowAddMul')]
  [&Category(fcMath)]
  FCN_RowAddMul = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RowEchelonForm')]
  [&Category(fcMath)]
  FCN_RowEchelonForm = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReducedRowEchelonForm')]
  [&Category(fcMath)]
  FCN_ReducedRowEchelonForm = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ZeroRowCount')]
  [&Category(fcMath)]
  FCN_NumZeroRows = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TrailingZeroRowCount')]
  [&Category(fcMath)]
  FCN_NumTrailingZeroRows = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GramSchmidt')]
  [&Category(fcMath)]
  FCN_GramSchmidt = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ColumnSpaceBasis')]
  [&Category(fcMath)]
  FCN_ColumnSpaceBasis = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ColumnSpaceProjection')]
  [&Category(fcMath)]
  FCN_ColumnSpaceProjection = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DistanceFromColumnSpace')]
  [&Category(fcMath)]
  FCN_DistanceFromColumnSpace = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('eigenvalues')]
  [&Category(fcMath)]
  FCN_Eigenvalues = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('spectrum')]
  [&Category(fcMath)]
  FCN_Spectrum = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('eigenvectors')]
  [&Category(fcMath)]
  FCN_Eigenvectors = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsEigenvector')]
  [&Category(fcMath)]
  FCN_IsEigenvector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('EigenvalueOf')]
  [&Category(fcMath)]
  FCN_EigenvalueOf = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsEigenpair')]
  [&Category(fcMath)]
  FCN_IsEigenpair = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('EigenvectorOf')]
  [&Category(fcMath)]
  FCN_EigenvectorOf = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SpectralRadius')]
  [&Category(fcMath)]
  FCN_SpectralRadius = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SingularValues')]
  [&Category(fcMath)]
  FCN_SingularValues = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('defuzz')]
  [&Category(fcMath)]
  FCN_Defuzz = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('vectorization', 'vec')]
  [&Category(fcMath)]
  FCN_Vectorization = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('aug')]
  [&Category(fcMath)]
  FCN_Aug = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SubmatrixByRemoval')]
  [&Category(fcMath)]
  FCN_SubmatrixByRemoval = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LeadingPrincipalSubmatrix')]
  [&Category(fcMath)]
  FCN_LeadingPrincipalSubmatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('lessen')]
  [&Category(fcMath)]
  FCN_Lessen = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('minor')]
  [&Category(fcMath)]
  FCN_Minor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('cofactor')]
  [&Category(fcMath)]
  FCN_Cofactor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CofactorMatrix')]
  [&Category(fcMath)]
  FCN_CofactorMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AdjugateMatrix')]
  [&Category(fcMath)]
  FCN_AdjugateMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LU')]
  [&Category(fcMath)]
  FCN_LU = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Cholesky')]
  [&Category(fcMath)]
  FCN_Cholesky = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('QR')]
  [&Category(fcMath)]
  FCN_QR = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('Hessenberg')]
  [&Category(fcMath)]
  FCN_Hessenberg = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SameValue')]
  [&Category(fcGeneral, fcMath)]
  FCN_SameValue = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CompareValue')]
  [&Category(fcGeneral, fcMath)]
  FCN_CompareValue = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ZeroMatrix')]
  [&Category(fcMath)]
  FCN_ZeroMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ComplexZeroMatrix')]
  [&Category(fcMath)]
  FCN_ComplexZeroMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IdentityMatrix')]
  [&Category(fcMath)]
  FCN_IdentityMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReversalMatrix')]
  [&Category(fcMath)]
  FCN_ReversalMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RandomMatrix')]
  [&Category(fcMath)]
  FCN_RandomMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RandomIntMatrix')]
  [&Category(fcMath)]
  FCN_RandomIntMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('OuterProduct')]
  [&Category(fcMath)]
  FCN_OuterProduct = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CirculantMatrix')]
  [&Category(fcMath)]
  FCN_CirculantMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToeplitzMatrix')]
  [&Category(fcMath)]
  FCN_ToeplitzMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('HankelMatrix')]
  [&Category(fcMath)]
  FCN_HankelMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('BackwardShiftMatrix')]
  [&Category(fcMath)]
  FCN_BackwardShiftMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ForwardShiftMatrix')]
  [&Category(fcMath)]
  FCN_ForwardShiftMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('VandermondeMatrix')]
  [&Category(fcMath)]
  FCN_VandermondeMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('HilbertMatrix')]
  [&Category(fcMath)]
  FCN_HilbertMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RotationMatrix')]
  [&Category(fcMath)]
  FCN_RotationMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ReflectionMatrix')]
  [&Category(fcMath)]
  FCN_ReflectionMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('HadamardProduct')]
  [&Category(fcMath)]
  FCN_HadamardProduct = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DirectSum')]
  [&Category(fcMath)]
  FCN_DirectSum = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ForwardSubstitution')]
  [&Category(fcMath)]
  FCN_ForwardSubstitution = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('BackSubstitution')]
  [&Category(fcMath)]
  FCN_BackSubstitution = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SysSolve')]
  [&Category(fcMath)]
  FCN_SysSolve = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LeastSquaresPolynomialFit', 'polyfit')]
  [&Category(fcMath)]
  FCN_LeastSquaresPolynomialFit = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AreParallel')]
  [&Category(fcMath)]
  FCN_AreParallel = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AreNotParallel')]
  [&Category(fcMath)]
  FCN_AreNotParallel = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ArePerpendicular')]
  [&Category(fcMath)]
  FCN_ArePerpendicular = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GetRGB')]
  [&Category(fcPixmaps)]
  FCN_RGBValues = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GetHSV')]
  [&Category(fcPixmaps)]
  FCN_HSVValues = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GetHSL')]
  [&Category(fcPixmaps)]
  FCN_HSLValues = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('color')]
  [&Category(fcPixmaps)]
  FCN_Color = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('HexColorCode')]
  [&Category(fcPixmaps)]
  FCN_HexColorCode = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NamedColors')]
  [&Category(fcPixmaps)]
  FCN_GetNamedColors = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsDark')]
  [&Category(fcPixmaps)]
  FCN_IsDark = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rgb')]
  [&Category(fcPixmaps)]
  FCN_RGB = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('hsv')]
  [&Category(fcPixmaps)]
  FCN_HSV = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('hsl')]
  [&Category(fcPixmaps)]
  FCN_HSL = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AddMember')]
  [&Category(fcStructures)]
  FCN_AddMember = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RemoveMember')]
  [&Category(fcStructures)]
  FCN_RemoveMember = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetValue')]
  [&Category(fcStructures)]
  FCN_SetValue = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RenameMember')]
  [&Category(fcStructures)]
  FCN_RenameMember = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('HasMember')]
  [&Category(fcStructures)]
  FCN_HasMember = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('IndexOfName')]
  [&Category(fcStructures)]
  FCN_IndexOfName = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('ToStructType')]
  [&Category(fcStructures)]
  FCN_ToStructType = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('new')]
  [&Category(fcStructures)]
  FCN_New = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GetStructType')]
  [&Category(fcStructures)]
  FCN_StructType = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RegisterStructType')]
  [&Category(fcStructures)]
  FCN_RegisterStructType = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('UnregisterStructType')]
  [&Category(fcStructures)]
  FCN_UnregisterStructType = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ValidateStruct')]
  [&Category(fcStructures)]
  FCN_ValidateStruct = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CreatePixmap')]
  [&Category(fcPixmaps)]
  FCN_CreatePixmap = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AddBorder')]
  [&Category(fcPixmaps)]
  FCN_AddBorder = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ExtendBorder')]
  [&Category(fcPixmaps)]
  FCN_ExtendBorder = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ColorFreqs')]
  [&Category(fcPixmaps)]
  FCN_ColorFrequencies = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ColorCount')]
  [&Category(fcPixmaps)]
  FCN_ColorCount = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FillRect')]
  [&Category(fcPixmaps)]
  FCN_FillRect = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DrawRect')]
  [&Category(fcPixmaps)]
  FCN_DrawRect = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AlphaDrawRect')]
  [&Category(fcPixmaps)]
  FCN_AlphaDrawRect = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FixHue')]
  [&Category(fcPixmaps)]
  FCN_FixHue = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToMonochromatic')]
  [&Category(fcPixmaps)]
  FCN_ToMonochromatic = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ShiftHue')]
  [&Category(fcPixmaps)]
  FCN_ShiftHue = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ToGreyscale')]
  [&Category(fcPixmaps)]
  FCN_ToGreyscale = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('InvertColor')]
  [&Category(fcPixmaps)]
  FCN_InvertColor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('InvertValue')]
  [&Category(fcPixmaps)]
  FCN_InvertValue = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('InvertLightness')]
  [&Category(fcPixmaps)]
  FCN_InvertLightness = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AdjustRGB')]
  [&Category(fcPixmaps)]
  FCN_RGBAdjustment = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AdjustHSV')]
  [&Category(fcPixmaps)]
  FCN_HSVAdjustment = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('binarize')]
  [&Category(fcPixmaps)]
  FCN_Binarize = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('flip')]
  [&Category(fcPixmaps)]
  FCN_Flip = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rot90p')]
  [&Category(fcPixmaps)]
  FCN_Rot90P = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rot90n')]
  [&Category(fcPixmaps)]
  FCN_Rot90N = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rot180')]
  [&Category(fcPixmaps)]
  FCN_Rot180 = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ScanlineRotation')]
  [&Category(fcPixmaps)]
  FCN_ScanlineRotation = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CustomScanlineRotation')]
  [&Category(fcPixmaps)]
  FCN_CustomScanlineRotation = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('SkewRotation')]
  [&Category(fcPixmaps)]
  FCN_SkewRotation = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('scale')]
  [&Category(fcPixmaps)]
  FCN_Scale = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('stretch')]
  [&Category(fcPixmaps)]
  FCN_Stretch = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rotate')]
  [&Category(fcPixmaps)]
  FCN_Rotate = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('shear')]
  [&Category(fcPixmaps)]
  FCN_Shear = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LinearTransformation')]
  [&Category(fcPixmaps)]
  FCN_ApplyLinearTransformation = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('transformation')]
  [&Category(fcPixmaps)]
  FCN_ApplyTransformation = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('GetRect')]
  [&Category(fcPixmaps)]
  FCN_GetRect = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AverageColor')]
  [&Category(fcPixmaps)]
  FCN_AverageColor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AutoCropRect')]
  [&Category(fcPixmaps)]
  FCN_GetAutoCropRect = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AutoCrop')]
  [&Category(fcPixmaps)]
  FCN_AutoCrop = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ExpandCanvas')]
  [&Category(fcPixmaps)]
  FCN_ExpandCanvas = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsOnlyBackground')]
  [&Category(fcPixmaps)]
  FCN_OnlyBackground = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('EdgeDetect')]
  [&Category(fcPixmaps)]
  FCN_DetectEdges = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('emboss')]
  [&Category(fcPixmaps)]
  FCN_Emboss = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('pixelate')]
  [&Category(fcPixmaps)]
  FCN_Pixellate = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('noise')]
  [&Category(fcPixmaps)]
  FCN_Noise = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DistortMetric')]
  [&Category(fcPixmaps)]
  FCN_DistortMetric = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DistortColor')]
  [&Category(fcPixmaps)]
  FCN_DistortColor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('tiles')]
  [&Category(fcPixmaps)]
  FCN_Tiles = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ComponentHighlight')]
  [&Category(fcPixmaps)]
  FCN_ComponentHighlight = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FloodFill')]
  [&Category(fcPixmaps)]
  FCN_FloodFill = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DrawLine')]
  [&Category(fcPixmaps)]
  FCN_DrawLine = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DrawLines')]
  [&Category(fcPixmaps)]
  FCN_DrawLines = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DrawPolygon')]
  [&Category(fcPixmaps)]
  FCN_DrawPolygon = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('convolve')]
  [&Category(fcPixmaps)]
  FCN_Convolve = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ConvolutionKernel')]
  [&Category(fcPixmaps)]
  FCN_ConvolutionKernel = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MotionBlur')]
  [&Category(fcPixmaps)]
  FCN_MotionBlur = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('BoxBlur')]
  [&Category(fcPixmaps)]
  FCN_BoxBlur = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GaussianBlur')]
  [&Category(fcPixmaps)]
  FCN_GaussianBlur = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('darken')]
  [&Category(fcPixmaps)]
  FCN_Darken = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('whiten')]
  [&Category(fcPixmaps)]
  FCN_Whiten = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FadeToColor')]
  [&Category(fcPixmaps)]
  FCN_FadeToColor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DissolveToColorRegularly')]
  [&Category(fcPixmaps)]
  FCN_EveryOtherToColor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DissolveToColorStochastically')]
  [&Category(fcPixmaps)]
  FCN_RandomToColor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('wind')]
  [&Category(fcPixmaps)]
  FCN_Wind = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RandomScanlineRotation')]
  [&Category(fcPixmaps)]
  FCN_RandomScanlineRotation = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ripple')]
  [&Category(fcPixmaps)]
  FCN_Ripple = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ExtractChannel')]
  [&Category(fcPixmaps, fcSounds)]
  FCN_ExtractChannel = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CombineChannels')]
  [&Category(fcPixmaps)]
  FCN_CombineChannels = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsGreyscale')]
  [&Category(fcPixmaps)]
  FCN_IsGreyscale = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DrawDisk')]
  [&Category(fcPixmaps)]
  FCN_DrawDisk = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DrawDisks')]
  [&Category(fcPixmaps)]
  FCN_DrawDisks = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DrawSquare')]
  [&Category(fcPixmaps)]
  FCN_DrawSquare = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DrawSquares')]
  [&Category(fcPixmaps)]
  FCN_DrawSquares = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ColorGradient')]
  [&Category(fcPixmaps)]
  FCN_CreateGradient = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('voronoi')]
  [&Category(fcPixmaps)]
  FCN_Voronoi = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('superpose')]
  [&Category(fcSounds)]
  FCN_SuperposeSounds = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AppendSound')]
  [&Category(fcSounds)]
  FCN_AppendSound = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('echo')]
  [&Category(fcSounds)]
  FCN_EchoSound = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ScaleAmplitude')]
  [&Category(fcSounds)]
  FCN_SoundScaleAmplitude = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ConvertAudio')]
  [&Category(fcSounds)]
  FCN_SoundConvertTo = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SineTone')]
  [&Category(fcSounds)]
  FCN_SineTone = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('WhiteNoise')]
  [&Category(fcSounds)]
  FCN_WhiteNoise = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MultichannelAudio')]
  [&Category(fcSounds)]
  FCN_MultichannelSound = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FadeSounds')]
  [&Category(fcSounds)]
  FCN_FadeSounds = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ComputeSound')]
  [&Category(fcSounds)]
  FCN_ComputeSound = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('AudioMetadata')]
  [&Category(fcSounds)]
  FCN_SoundMetadata = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('SoundMax')]
  [&Category(fcSounds)]
  FCN_SoundMax = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('PlaySound')]
  [&Category(fcSounds)]
  FCN_PlaySound = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('StopSound')]
  [&Category(fcSounds)]
  FCN_StopSound = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetInstrument')]
  [&Category(fcMIDI)]
  FCN_SetInstrument = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GetInstrument')]
  [&Category(fcMIDI)]
  FCN_GetInstrument = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SetVolume')]
  [&Category(fcMIDI)]
  FCN_SetVolume = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GetVolume')]
  [&Category(fcMIDI)]
  FCN_GetVolume = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NoteOn')]
  [&Category(fcMIDI)]
  FCN_NoteOn = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NoteOff')]
  [&Category(fcMIDI)]
  FCN_NoteOff = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('PercussionNoteOn')]
  [&Category(fcMIDI)]
  FCN_PNoteOn = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('PercussionNoteOff')]
  [&Category(fcMIDI)]
  FCN_PNoteOff = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NoteSilence')]
  [&Category(fcMIDI)]
  FCN_NoteSilence = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NoteReset')]
  [&Category(fcMIDI)]
  FCN_NoteReset = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('InstrumentInfo')]
  [&Category(fcMIDI)]
  FCN_InstrumentInfo = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('PercussionInstrumentInfo')]
  [&Category(fcMIDI)]
  FCN_PInstrumentInfo = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NoteName')]
  [&Category(fcMIDI)]
  FCN_NoteName = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MidiMsg')]
  [&Category(fcMIDI)]
  FCN_MidiMsg = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('label')]
  [&Category(fcLists)]
  FCN_LabelList = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('VarAppend')]
  [&Category(fcGeneral, fcLists)]
  FCN_VarAppend = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('VarExtendWith')]
  [&Category(fcGeneral, fcLists)]
  FCN_VarExtendWith = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('catenate', 'concatenate', 'concat')]
  [&Category(fcGeneral, fcLists)]
  FCN_Catenate = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('VarInsert')]
  [&Category(fcGeneral, fcLists)]
  FCN_VarInsert = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('VarRemove')]
  [&Category(fcGeneral, fcLists)]
  FCN_VarRemove = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('VarTruncate')]
  [&Category(fcGeneral, fcLists)]
  FCN_VarTruncate = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('VarSwap')]
  [&Category(fcGeneral, fcLists)]
  FCN_VarSwap = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('numbers')]
  [&Category(fcGeneral, fcLists)]
  FCN_Numbers = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('CreateFunction')]
  [&Category(fcSystem)]
  FCN_CreateFunction = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('image')]
  [&Category(fcSystem)]
  FCN_Image = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IteratedImage')]
  [&Category(fcSystem)]
  FCN_IteratedImage = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IteratedImages')]
  [&Category(fcSystem)]
  FCN_IteratedImages = class(TASSimpleFunction)
  protected
    var
      FContainerClass: TAlgosimObjectClass;
    procedure SimpleFunction; override;
    procedure InitNode; override;
  end;

  [&Function('orbit')]
  [&Category(fcSystem)]
  FCN_Orbit = class(FCN_IteratedImages)
  protected
    procedure InitNode; override;
  end;

  [&Function('IsNumber')]
  [&Category(fcSystem)]
  FCN_IsNumber = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsVector')]
  [&Category(fcSystem)]
  FCN_IsVector = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsMatrix')]
  [&Category(fcSystem)]
  FCN_IsMatrix = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsText')]
  [&Category(fcSystem)]
  FCN_IsText = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsBoolean')]
  [&Category(fcSystem)]
  FCN_IsBoolean = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsPixmap')]
  [&Category(fcSystem)]
  FCN_IsPixmap = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsSound')]
  [&Category(fcSystem)]
  FCN_IsSound = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsTable')]
  [&Category(fcSystem)]
  FCN_IsTable = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsColor')]
  [&Category(fcSystem)]
  FCN_IsColor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsSet')]
  [&Category(fcSystem)]
  FCN_IsSet = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsList')]
  [&Category(fcSystem)]
  FCN_IsList = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsStructure')]
  [&Category(fcSystem)]
  FCN_IsStructure = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsReal')]
  [&Category(fcSystem)]
  FCN_IsReal = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsComplex')]
  [&Category(fcSystem)]
  FCN_IsComplex = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsInteger')]
  [&Category(fcSystem)]
  FCN_IsInteger = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsNumericEntity')]
  [&Category(fcSystem)]
  FCN_IsNumericEntity = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsNumericArray')]
  [&Category(fcSystem)]
  FCN_IsNumericArray = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsBinaryData')]
  [&Category(fcSystem)]
  FCN_IsBinaryData = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('entrywise')]
  [&Category(fcLists, fcMath)]
  FCN_entrywise = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('accumulate')]
  [&Category(fcGeneral, fcLists, fcMath)]
  FCN_Accumulate = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AccumulateList')]
  [&Category(fcGeneral, fcLists, fcMath)]
  FCN_AccumulateList = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AccumulateSteps')]
  [&Category(fcGeneral, fcLists, fcMath)]
  FCN_AccumulateSteps = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rest')]
  [&Category(fcGeneral, fcLists)]
  FCN_Rest = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('append')]
  [&Category(fcGeneral, fcLists)]
  FCN_Append = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ExtendWith')]
  [&Category(fcGeneral, fcLists)]
  FCN_ExtendWith = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('insert')]
  [&Category(fcGeneral, fcLists)]
  FCN_Insert = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('remove')]
  [&Category(fcGeneral, fcLists)]
  FCN_Remove = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('truncate')]
  [&Category(fcGeneral, fcLists)]
  FCN_Truncate = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('swap')]
  [&Category(fcGeneral, fcLists)]
  FCN_Swap = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SortBy')]
  [&Category(fcGeneral, fcLists)]
  FCN_SortBy = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('member')]
  [&Category(fcStructures)]
  FCN_Member = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('GroupBy')]
  [&Category(fcGeneral, fcLists)]
  FCN_GroupBy = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('characters')]
  [&Category(fcStrings)]
  FCN_Characters = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('words')]
  [&Category(fcStrings)]
  FCN_Words = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('do')]
  [&Category(fcSystem)]
  FCN_Do = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('divides')]
  [&Category(fcMath)]
  FCN_Divides = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('NotDivides')]
  [&Category(fcMath)]
  FCN_NotDivides = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('primorial')]
  [&Category(fcMath)]
  FCN_Primorial = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('inc')]
  [&Category(fcMath)]
  FCN_Inc = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('dec')]
  [&Category(fcMath)]
  FCN_Dec = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('variables')]
  [&Category(fcSystem)]
  FCN_Variables = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LastError')]
  [&Category(fcSystem)]
  FCN_LastError = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('functions')]
  [&Category(fcSystem)]
  FCN_Functions = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  TKernelFunctionFcn = class abstract(TASSimpleFunction)
  protected
    procedure SimpleFunction; override; final;
    procedure Fcn(AFcnClass: TASFunctionClass); virtual; abstract;
  end;

  [&Function('function')]
  [&Category(fcSystem)]
  FCN_Function = class(TKernelFunctionFcn)
  protected
    procedure Fcn(AFcnClass: TASFunctionClass); override;
  end;

  [&Function('categories')]
  [&Category(fcSystem)]
  FCN_Categories = class(TKernelFunctionFcn)
  protected
    procedure Fcn(AFcnClass: TASFunctionClass); override;
  end;

  [&Function('FcnName')]
  [&Category(fcSystem)]
  FCN_FcnName = class(TKernelFunctionFcn)
  protected
    procedure Fcn(AFcnClass: TASFunctionClass); override;
  end;

  [&Function('FcnNames')]
  [&Category(fcSystem)]
  FCN_FcnNames = class(TKernelFunctionFcn)
  protected
    procedure Fcn(AFcnClass: TASFunctionClass); override;
  end;

  [&Function('ErrorInfo')]
  [&Category(fcSystem)]
  FCN_ErrorInfo = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('succ')]
  [&Category(fcMath)]
  FCN_Succ = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('pred')]
  [&Category(fcMath)]
  FCN_Pred = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LoadDefVars')]
  [&Category(fcSystem)]
  FCN_LoadDefVars = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('operators')]
  [&Category(fcSystem)]
  FCN_Operators = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('if')]
  [&Category(fcSystem)]
  FCN_If = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('ForEach')]
  [&Category(fcGeneral, fcLists, fcStrings, fcStructures, fcSets)]
  FCN_ForEach = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('print')]
  [&Category(fcSystem)]
  FCN_Print = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RemoveBuffer')]
  [&Category(fcSystem)]
  FCN_RemoveBuffer = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('BufferText')]
  [&Category(fcSystem)]
  FCN_BufferText = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('buffers')]
  [&Category(fcSystem)]
  FCN_Buffers = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MessageBox')]
  [&Category(fcSystem)]
  FCN_MessageBox = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('InputBox')]
  [&Category(fcSystem)]
  FCN_InputBox = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FormatDateTime')]
  [&Category(fcDateTime)]
  FCN_FormatDateTime = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DateTimeString')]
  [&Category(fcDateTime)]
  FCN_DateTimeString = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DateString')]
  [&Category(fcDateTime)]
  FCN_DateString = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TimeString')]
  [&Category(fcDateTime)]
  FCN_TimeString = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('while')]
  [&Category(fcSystem)]
  FCN_While = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('until')]
  [&Category(fcSystem)]
  FCN_Until = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('repeat')]
  [&Category(fcSystem)]
  FCN_Repeat = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('for')]
  [&Category(fcSystem)]
  FCN_For = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('tokenize')]
  [&Category(fcSystem)]
  FCN_Tokenize = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('parse')]
  [&Category(fcSystem)]
  FCN_Parse = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('WordWrap')]
  [&Category(fcStrings)]
  FCN_WordWrap = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('history')]
  [&Category(fcSystem)]
  FCN_History = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('input')]
  [&Category(fcSystem)]
  FCN_Input = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('inputs')]
  [&Category(fcSystem)]
  FCN_Inputs = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('output')]
  [&Category(fcSystem)]
  FCN_Output = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('HistoryLength')]
  [&Category(fcSystem)]
  FCN_HistoryLength = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ClearHistory')]
  [&Category(fcSystem)]
  FCN_ClearHistory = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SaveHistory')]
  [&Category(fcSystem)]
  FCN_SaveHistory = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SelfTest')]
  [&Category(fcSystem)]
  FCN_SelfTest = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('bases')]
  [&Category(fcSystem)]
  FCN_Bases = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FcnExpr')]
  [&Category(fcSystem)]
  FCN_FcnExpr = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RandomColor')]
  [&Category(fcPixmaps)]
  FCN_RandomColor = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('compute')]
  [&Category(fcLists, fcMath, fcGeneral)]
  FCN_Compute = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('DebugObject')]
  [&Category(fcSystem)]
  FCN_DebugObject = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CompareString')]
  [&Category(fcStrings)]
  FCN_CompareString = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsCharacter')]
  [&Category(fcSystem)]
  FCN_IsCharacter = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsRealType')]
  [&Category(fcSystem)]
  FCN_IsRealType = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsComplexType')]
  [&Category(fcSystem)]
  FCN_IsComplexType = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('break')]
  [&Category(fcSystem)]
  FCN_Break = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('continue')]
  [&Category(fcSystem)]
  FCN_Continue = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SquareWave')]
  [&Category(fcMath)]
  FCN_SquareWave = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('TriangleWave')]
  [&Category(fcMath)]
  FCN_TriangleWave = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('SawtoothWave')]
  [&Category(fcMath)]
  FCN_SawtoothWave = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('BlendModes')]
  [&Category(fcPixmaps)]
  FCN_BlendModes = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  TNamedObjFcn = class abstract(TASFunction)
  protected
    procedure DoExecute; override; final;
    procedure HandleNamedObject(AObject: TAlgosimObject; const AName: string);
      virtual; abstract;
  end;

  [&Function('display')]
  [&Category(fcSystem)]
  FCN_Display = class(TNamedObjFcn)
  protected
    procedure HandleNamedObject(AObject: TAlgosimObject; const AName: string);
      override;
  end;

  [&Function('window')]
  [&Category(fcSystem)]
  FCN_Window = class(TNamedObjFcn)
  protected
    procedure HandleNamedObject(AObject: TAlgosimObject; const AName: string);
      override;
  end;

  [&Function('ComputePixmap')]
  [&Category(fcPixmaps)]
  FCN_ComputePixmap = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('ColorDialog')]
  [&Category(fcSystem)]
  FCN_ColorDialog = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FontDialog')]
  [&Category(fcSystem)]
  FCN_FontDialog = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FileExists')]
  [&Category(fcSystem)]
  FCN_FileExists = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FileSize')]
  [&Category(fcSystem)]
  FCN_FileSize = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FileName')]
  [&Category(fcSystem)]
  FCN_FileName = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('PrettyFileName')]
  [&Category(fcSystem)]
  FCN_PrettyFileName = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FilePath')]
  [&Category(fcSystem)]
  FCN_FilePath = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FileExt')]
  [&Category(fcSystem)]
  FCN_FileExt = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DeleteFile')]
  [&Category(fcSystem)]
  FCN_DeleteFile = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CreateDirectory')]
  [&Category(fcSystem)]
  FCN_CreateDirectory = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DeleteDirectory')]
  [&Category(fcSystem)]
  FCN_DeleteDirectory = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DirectoryExists')]
  [&Category(fcSystem)]
  FCN_DirectoryExists = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FileList')]
  [&Category(fcSystem)]
  FCN_FileList = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('DirectoryList')]
  [&Category(fcSystem)]
  FCN_DirectoryList = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FileOpenDialog')]
  [&Category(fcSystem)]
  FCN_FileOpenDialog = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FileSaveDialog')]
  [&Category(fcSystem)]
  FCN_FileSaveDialog = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('IsCarolNumber')]
  [&Category(fcMath, fcNumberTheory)]
  FCN_IsCarolNumber = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('StructKeys')]
  [&Category(fcSystem)]
  FCN_StructKeys = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('digits')]
  [&Category(fcSystem)]
  FCN_Digits = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('FractionParts')]
  [&Category(fcSystem)]
  FCN_FractionParts = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ExampleData')]
  [&Category(fcGeneral)]
  FCN_ExampleData = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LeftAlign')]
  [&Category(fcTables)]
  FCN_LeftAlign = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RightAlign')]
  [&Category(fcTables)]
  FCN_RightAlign = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CenterText')]
  [&Category(fcTables)]
  FCN_CenterText = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MatrixPlot')]
  [&Category(fcMath, fcPixmaps)]
  FCN_MatrixPlot = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('diagram')]
  [&Category(fcVisualization)]
  FCN_Diagram = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('scene')]
  [&Category(fcVisualization)]
  FCN_Scene = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  TASVisualizationFunction = class(TASSimpleFunction)
  strict protected
    FVisual: TObject;
    procedure SimpleFunction; override;
  public
    destructor Destroy; override;
  end;

  [&Function('BarChart')]
  [&Category(fcVisualization)]
  FCN_BarChart = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('PieChart')]
  [&Category(fcVisualization)]
  FCN_PieChart = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('histogram')]
  [&Category(fcVisualization)]
  FCN_Histogram = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ScatterPlot')]
  [&Category(fcVisualization)]
  FCN_ScatterPlot = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LineChart', 'LinePlot')]
  [&Category(fcVisualization)]
  FCN_LineChart = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AreaChart')]
  [&Category(fcVisualization)]
  FCN_AreaChart = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('graph')]
  [&Category(fcSystem, fcVisualization)]
  FCN_Graph = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('plot')]
  [&Category(fcVisualization)]
  FCN_Plot = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('heatmap')]
  [&Category(fcVisualization)]
  FCN_Heatmap = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('VectorField')]
  [&Category(fcVisualization)]
  FCN_VectorField = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('RemoveVisual')]
  [&Category(fcVisualization)]
  FCN_RemoveVisual = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('AdjustVisual')]
  [&Category(fcVisualization)]
  FCN_AdjustVisual = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('LineSegment')]
  [&Category(fcVisualization)]
  FCN_LineSegment = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('rectangle')]
  [&Category(fcVisualization)]
  FCN_Rectangle = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('circle')]
  [&Category(fcVisualization)]
  FCN_Circle = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('disk')]
  [&Category(fcVisualization)]
  FCN_Disk = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('polygon')]
  [&Category(fcVisualization)]
  FCN_Polygon = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('text')]
  [&Category(fcVisualization)]
  FCN_Text = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('EmbedPixmap')]
  [&Category(fcPixmaps, fcVisualization)]
  FCN_EmbedPixmap = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('speak')]
  [&Category(fcSystem)]
  FCN_Speak = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('surface', 'surf')]
  [&Category(fcVisualization)]
  FCN_Surface = class(TASFunction)
  protected
    procedure DoExecute; override;
  end;

  [&Function('curve')]
  [&Category(fcVisualization)]
  FCN_Curve = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('sphere')]
  [&Category(fcVisualization)]
  FCN_Sphere = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ellipsoid')]
  [&Category(fcVisualization)]
  FCN_Ellipsoid = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('cylinder')]
  [&Category(fcVisualization)]
  FCN_Cylinder = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('cone')]
  [&Category(fcVisualization)]
  FCN_Cone = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('plane')]
  [&Category(fcVisualization)]
  FCN_Plane = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('InfinitePlane')]
  [&Category(fcVisualization)]
  FCN_InfinatePlane = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('disk3D')]
  [&Category(fcVisualization)]
  FCN_Disk3D = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('solid')]
  [&Category(fcVisualization)]
  FCN_Solid = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('model')]
  [&Category(fcVisualization)]
  FCN_Model = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('CoordinateAxes')]
  [&Category(fcVisualization)]
  FCN_CoordinateAxes = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('clamp')]
  [&Category(fcMath)]
  FCN_Clamp = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('paste')]
  [&Category(fcSystem)]
  FCN_Paste = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ClearScene')]
  [&Category(fcVisualization)]
  FCN_ClearScene = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('ClearDiagram')]
  [&Category(fcVisualization)]
  FCN_ClearDiagram = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('VisualObject')]
  [&Category(fcVisualization)]
  FCN_VisualObject = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('VisualObjects')]
  [&Category(fcVisualization)]
  FCN_VisualObjects = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('MemoryUsage')]
  [&Category(fcSystem)]
  FCN_MemoryUsage = class(TASSimpleFunction)
  protected
    procedure SimpleFunction; override;
  end;

  [&Function('arrow')]
  [&Category(fcVisualization)]
  FCN_Arrow = class(TASVisualizationFunction)
  protected
    procedure SimpleFunction; override;
  end;



var
  FixedTime: TDateTime;

implementation

uses
  Windows, Math, StrUtils, DateUtils, ASPropMan, ASPropStores, ASStrFcns,
  UnicodeData, ASTable, ASColors, ASPixmap, ASSounds, ASMIDI, ASTokenizer,
  ASParser, SyncObjs, IOUtils, ASNumUtils, ASVisualization, VisCtl2D, rgl,
  ASSpeech, Clipbrd, ClientVisuals, PsAPI;

const
  DefPlotN = 2000;

function GetCurDate: TDateTime;
begin
  if FixedTime <> 0.0 then
    Result := DateOf(FixedTime)
  else
    Result := SysUtils.Date
end;

function GetCurTime: TDateTime;
begin
  if FixedTime <> 0.0 then
    Result := TimeOf(FixedTime)
  else
    Result := SysUtils.Time
end;

function GetCurDateTime: TDateTime;
begin
  if FixedTime <> 0.0 then
    Result := FixedTime
  else
    Result := SysUtils.Now
end;

function GetYesterday: TDateTime;
begin
  if FixedTime <> 0.0 then
    Result := GetCurDate - 1 // mimics the implementation of DateUtils.Yesterday
  else
    Result := DateUtils.Yesterday
end;

function GetTomorrow: TDateTime;
begin
  if FixedTime <> 0.0 then
    Result := GetCurDate + 1 // mimics the implementation of DateUtils.Tomorrow
  else
    Result := DateUtils.Tomorrow;
end;


{ FCN_Identity }

procedure FCN_Identity.SimpleFunction;
begin
  Args.MoveObject(Value).Close;
end;

{ FCN_Add }

procedure FCN_Add.SimpleFunction;
var
  Args: TArgumentExtractor;
  Right: TAlgosimObject;
begin

  Args := Self.Args;

  if Args.Count = 0 then
  begin
    Result := ASO(0);
    Exit;
  end;

  Args := Args.MoveObject(Value);

  while Args.ArgExists do
  begin

    Args := Args.Extract(Right);

    if (Value is TAlgosimNumber) and (Right is TAlgosimNumber) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimNumber.Add(TAlgosimNumber(Value), TAlgosimNumber(Right)))

    else if (Value is TAlgosimVector) and (Right is TAlgosimVector) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimVector.Add(TAlgosimVector(Value), TAlgosimVector(Right)))

    else if (Value is TAlgosimMatrix) and (Right is TAlgosimMatrix) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimMatrix.Add(TAlgosimMatrix(Value), TAlgosimMatrix(Right)))

    else if (Value is TAlgosimString) and (Right is TAlgosimString) then
      TObjReplacer<TAlgosimObject>.Replace(Value, ASO(TAlgosimString(Value).Value + TAlgosimString(Right).Value))

    else if Value is TAlgosimString then
      TObjReplacer<TAlgosimObject>.Replace(Value, ASO(TAlgosimString(Value).Value + Right.GetAsSingleLineText(Context.FormatOptions)))

    else if (Value is TAlgosimVector) and (Right is TAlgosimNumber) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimVector.Add(TAlgosimVector(Value), TAlgosimNumber(Right)))

    else if (Value is TAlgosimMatrix) and (Right is TAlgosimNumber) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimMatrix.Add(TAlgosimMatrix(Value), TAlgosimNumber(Right)))

    else if (Value is TAlgosimSound) and (Right is TAlgosimSound) then
      TObjReplacer<TAlgosimObject>.Replace(Value, ASO(TAlgosimSound(Value).Value + TAlgosimSound(Right).Value))

    else
      ErrInvalidArguments;

  end;

end;

{ FCN_Subtract }

procedure FCN_Subtract.SimpleFunction;
var
  Left, Right: TAlgosimObject;
begin

  Args.Extract(Left).Extract(Right).Close;

  if (Left is TAlgosimNumber) and (Right is TAlgosimNumber) then
    Result := TAlgosimNumber.Subtract(TAlgosimNumber(Left), TAlgosimNumber(Right))

  else if (Left is TAlgosimVector) and (Right is TAlgosimVector) then
    Result := TAlgosimVector.Subtract(TAlgosimVector(Left), TAlgosimVector(Right))

  else if (Left is TAlgosimMatrix) and (Right is TAlgosimMatrix) then
    Result := TAlgosimMatrix.Subtract(TAlgosimMatrix(Left), TAlgosimMatrix(Right))

  else if (Left is TAlgosimVector) and (Right is TAlgosimNumber) then
    Result := TAlgosimVector.Subtract(TAlgosimVector(Left), TAlgosimNumber(Right))

  else if (Left is TAlgosimMatrix) and (Right is TAlgosimNumber) then
    Result := TAlgosimMatrix.Subtract(TAlgosimMatrix(Left), TAlgosimNumber(Right))

  else if (Left is TAlgosimSound) and (Right is TAlgosimSound) then
    Result := ASO(TAlgosimSound(Left).Value - TAlgosimSound(Right).Value)

  else
    ErrInvalidArguments;

end;

{ FCN_UnaryMinus }

procedure FCN_UnaryMinus.SimpleFunction;
var
  Obj: TAlgosimObject;
begin
  Args.Extract(Obj).Close;
  Result := Obj.UnaryMinus;
end;

{ FCN_Multiply }

procedure FCN_Multiply.SimpleFunction;
var
  Args: TArgumentExtractor;
  Right: TAlgosimObject;
  IntVal: Integer;
  RealVal: TASR;
begin

  Args := Self.Args;

  if Args.Count = 0 then
  begin
    Result := ASO(1);
    Exit;
  end;

  Args := Args.MoveObject(Value);

  while Args.ArgExists do
  begin

    Args := Args.Extract(Right);

    if (Value is TAlgosimNumber) and (Right is TAlgosimNumber) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimNumber.Multiply(TAlgosimNumber(Value), TAlgosimNumber(Right)))

    else if (Value is TAlgosimVector) and (Right is TAlgosimVector) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimVector.InnerProduct(TAlgosimVector(Value), TAlgosimVector(Right)))

    else if (Value is TAlgosimMatrix) and (Right is TAlgosimMatrix) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimMatrix.Multiply(TAlgosimMatrix(Value), TAlgosimMatrix(Right)))

    else if (Value is TAlgosimNumber) and (Right is TAlgosimVector) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimVector.Multiply(TAlgosimVector(Right), TAlgosimNumber(Value)))

    else if (Value is TAlgosimVector) and (Right is TAlgosimNumber) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimVector.Multiply(TAlgosimVector(Value), TAlgosimNumber(Right)))

    else if (Value is TAlgosimNumber) and (Right is TAlgosimMatrix) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimMatrix.Multiply(TAlgosimMatrix(Right), TAlgosimNumber(Value)))

    else if (Value is TAlgosimMatrix) and (Right is TAlgosimNumber) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimMatrix.Multiply(TAlgosimMatrix(Value), TAlgosimNumber(Right)))

    else if (Value is TAlgosimMatrix) and (Right is TAlgosimVector) then
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimMatrix.Multiply(TAlgosimMatrix(Value), TAlgosimVector(Right)))

    else if (Right is TAlgosimString) and (Value is TAlgosimNumber) and Value.TryToInt32(IntVal) and (IntVal >= 0) then
      TObjReplacer<TAlgosimObject>.Replace(Value, ASO(DupeString(TAlgosimString(Right).Value, IntVal)))

    else if (Value is TAlgosimString) and (Right is TAlgosimNumber) and Right.TryToInt32(IntVal) and (IntVal >= 0) then
      TObjReplacer<TAlgosimObject>.Replace(Value, ASO(DupeString(TAlgosimString(Value).Value, IntVal)))

    else if (Right is TAlgosimSound) and (Value is TAlgosimNumber) and Value.TryToASR(RealVal) then
      TObjReplacer<TAlgosimObject>.Replace(Value, ASO(RealVal * TAlgosimSound(Right).Value))

    else if (Value is TAlgosimSound) and (Right is TAlgosimSound) then
      TObjReplacer<TAlgosimObject>.Replace(Value, ASO(TAlgosimSound(Value).Value * TAlgosimSound(Right).Value))

    else
      ErrInvalidArguments;

  end;

end;

{ FCN_InnerProduct }

procedure FCN_InnerProduct.SimpleFunction;
var
  L, R: TAlgosimVector;
begin
  Args.Extract(L).Extract(R).Close;
  Result := TAlgosimVector.InnerProduct(L, R);
end;

{ FCN_Divide }

procedure FCN_Divide.SimpleFunction;
var
  Left, Right: TAlgosimObject;
begin

  Args.Extract(Left).Extract(Right).Close;

  if (Left is TAlgosimNumber) and (Right is TAlgosimNumber) then
    Result := TAlgosimNumber.Divide(TAlgosimNumber(Left), TAlgosimNumber(Right))

  else if (Left is TAlgosimVector) and (Right is TAlgosimNumber) then
    Result := TAlgosimVector.Divide(TAlgosimVector(Left), TAlgosimNumber(Right))

  else if (Left is TAlgosimMatrix) and (Right is TAlgosimNumber) then
    Result := TAlgosimMatrix.Divide(TAlgosimMatrix(Left), TAlgosimNumber(Right))

  else
    ErrInvalidArguments;

end;

{ FCN_Power }

procedure FCN_Power.SimpleFunction;
var
  Left, Right: TAlgosimObject;
  IntVal: Integer;
begin

  Args.Extract(Left).Extract(Right).Close;

  if (Left is TAlgosimNumber) and (Right is TAlgosimNumber) then
    Result := TAlgosimNumber.Power(TAlgosimNumber(Left), TAlgosimNumber(Right))

  else if (Left is TAlgosimMatrix) and (Right is TAlgosimNumber) and Right.TryToInt32(IntVal) then
    Result := TAlgosimMatrix(Left).Power(IntVal)

  else if (Left is TAlgosimSet) and (Right is TAlgosimNumber) and Right.TryToInt32(IntVal) and (IntVal > 0) then
    Result := TAlgosimSet.CartesianProduct(TAlgosimSet(Left), IntVal)

  else if (Left is TAlgosimArray) and (Right is TAlgosimNumber) and Right.TryToInt32(IntVal) and (IntVal > 0) then
    Result := TAlgosimArray.CartesianProduct(TAlgosimArray(Left), IntVal)

  else
    ErrInvalidArguments;

end;

{ FCN_Cross }

procedure FCN_Cross.SimpleFunction;
var
  Args: TArgumentExtractor;
  Right: TAlgosimVector;
  U, V: TAlgosimSet;
  sets: array of TAlgosimSet;
  arrs: array of TAlgosimArray;
begin
  Args := Self.Args;
  if Args.PeekAt(0) is TAlgosimVector then
  begin
    Args := Args.MoveObject(Value);
    while Args.ArgExists do
    begin
      Args := Args.Extract(Right);
      TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimVector.CrossProduct(TAlgosimVector(Value), Right))
    end;
  end
  else if Args.PeekAt(0) is TAlgosimArray then
  begin
    SetLength(arrs, Args.Count);
    for var i := 0 to Args.Count - 1 do
      Args := Args.Extract(arrs[i]);
    Result := TAlgosimArray.CartesianProduct(arrs);
  end
  else
  begin
    if Args.Count = 2 then // because it might be slightly faster
    begin
      Args.Extract(U).Extract(V).Close;
      Result := TAlgosimSet.CartesianProduct(U, V);
    end
    else
    begin
      SetLength(sets, Args.Count);
      for var i := 0 to Args.Count - 1 do
        Args := Args.Extract(sets[i]);
      Result := TAlgosimSet.CartesianProduct(sets);
    end;
  end;
end;

{ FCN_CrossProduct }

procedure FCN_CrossProduct.SimpleFunction;
var
  Right: TAlgosimVector;
  Args: TArgumentExtractor;
begin
  Args := Self.Args.MoveObject<TAlgosimVector>(Value);
  while Args.ArgExists do
  begin
    Args := Args.Extract(Right);
    TObjReplacer<TAlgosimObject>.Replace(Value, TAlgosimVector.CrossProduct(TAlgosimVector(Value), Right))
  end;
end;


{ FCN_Angle }

procedure FCN_Angle.SimpleFunction;
var
  Left, Right: TAlgosimVector;
begin
  Args.Extract(Left).Extract(Right).Close;
  Result := TAlgosimVector.Angle(Left, Right);
end;

{ FCN_Factorial }

procedure FCN_Factorial.SimpleFunction;
var
  N: Integer;
begin
  Args.ExtractNonNeg(N).Close;
  if InRange(N, Low(intfactorials), High(intfactorials)) then
    Result := ASOInt(intfactorials[N])
  else
    Result := ASO(factorial(N));
end;

{ FCN_Modulus }

procedure FCN_Absolute.SimpleFunction;
var
  Arg: TAlgosimNumericEntity;
begin
  Args.Extract(Arg).Close;
  Result := Arg.Abs;
end;

{ FCN_ConjugateTranspose }

procedure FCN_ConjugateTranspose.SimpleFunction;
var
  Arg: TAlgosimNumericEntity;
begin
  Args.Extract(Arg).Close;
  if Arg is TAlgosimNumber then
    Result := TAlgosimNumber(Arg).Conjugate
  else
    Result := Arg.ConjugateTranspose;
end;

{ FCN_Transpose }

procedure FCN_Transpose.SimpleFunction;
var
  Arg: TAlgosimObject;
begin

  Args.Extract(Arg).Close;

  if Arg is TAlgosimNumericEntity then
    Result := TAlgosimNumericEntity(Arg).Transpose

  else if Arg is TAlgosimArray then
    Result := TAlgosimArray(Arg).Transpose

  else
    ErrInvalidArguments;

end;

{ FCN_Argument }

procedure FCN_Argument.SimpleFunction;
var
  Arg: TAlgosimNumber;
begin
  Args.Extract(Arg).Close;
  Result := Arg.Argument;
end;

{ FCN_RealPart }

procedure FCN_RealPart.SimpleFunction;
var
  Arg: TAlgosimNumericEntity;
begin
  Args.Extract(Arg).Close;
  Result := Arg.RealPart;
end;

{ FCN_ImaginaryPart }

procedure FCN_ImaginaryPart.SimpleFunction;
var
  Arg: TAlgosimNumericEntity;
begin
  Args.Extract(Arg).Close;
  Result := Arg.ImaginaryPart;
end;

{ FCN_sqrt }

procedure FCN_Sqrt.SimpleFunction;
const
  rdom_sqrt: TSDD = (a: 0; Kind: sddGeq; Complement: False);
var
  Arg: TAlgosimNumericEntity;
begin

  Args.Extract(Arg).Close;

  if Arg is TAlgosimNumber then
    Result := TAlgosimNumber(Arg).ComputeFunction(rdom_sqrt, sqrt, csqrt)

  else if Arg is TAlgosimMatrix then
  begin
    if Arg is TAlgosimRealMatrix then
      Result := ASO(sqrt(TAlgosimRealMatrix(Arg).Value))
    else if Arg is TAlgosimComplexMatrix then
      Result := ASO(sqrt(TAlgosimComplexMatrix(Arg).Value));
  end

  else
    ErrInvalidArguments;

end;

{ FCN_Deg }

class constructor FCN_Deg.ClassCreate;
begin
  PiDiv180 := ASO(Pi / 180);
end;

class destructor FCN_Deg.ClassDestroy;
begin
  FreeAndNil(PiDiv180);
end;

procedure FCN_Deg.SimpleFunction;
var
  Arg: TAlgosimNumber;
begin
  Args.Extract(Arg).Close;
  Result := TAlgosimNumber.Multiply(Arg, PiDiv180);
end;

{ FCN_Percent }

class constructor FCN_Percent.ClassCreate;
begin
  OneHundredth := ASO(1 / 100);
end;

class destructor FCN_Percent.ClassDestroy;
begin
  FreeAndNil(OneHundredth);
end;

procedure FCN_Percent.SimpleFunction;
var
  Arg: TAlgosimNumber;
begin
  Args.Extract(Arg).Close;
  Result := TAlgosimNumber.Multiply(Arg, OneHundredth);
end;

{ FCN_Permille }

class constructor FCN_Permille.ClassCreate;
begin
  OneThousandth := ASO(1 / 1000);
end;

class destructor FCN_Permille.ClassDestroy;
begin
  FreeAndNil(OneThousandth);
end;

procedure FCN_Permille.SimpleFunction;
var
  Arg: TAlgosimNumber;
begin
  Args.Extract(Arg).Close;
  Result := TAlgosimNumber.Multiply(Arg, OneThousandth);
end;

{ FCN_Square }

procedure FCN_Square.SimpleFunction;
var
  Arg: TAlgosimNumericEntity;
begin
  Args.Extract(Arg).Close;
  Result := Arg.Square;
end;

{ FCN_sin }

procedure FCN_sin.InitNode;
begin
  rfcn := sin;
  cfcn := csin;
end;

{ FCN_cos }

procedure FCN_cos.InitNode;
begin
  rfcn := cos;
  cfcn := ccos;
end;

{ FCN_tan }

procedure FCN_tan.InitNode;
begin
  rfcn := tan;
  cfcn := ctan;
end;

{ FCN_cot }

procedure FCN_cot.InitNode;
begin
  rfcn := cot;
  cfcn := ccot;
end;

{ FCN_sec }

procedure FCN_sec.InitNode;
begin
  rfcn := sec;
  cfcn := csec;
end;

{ FCN_csc }

procedure FCN_csc.InitNode;
begin
  rfcn := csc;
  cfcn := ccsc;
end;

{ FCN_arcsin }

procedure FCN_arcsin.InitNode;
const
  rdom_arcsin: TSDD = (a: -1; b: 1; Kind: sddBii; Complement: False);
begin
  inherited;
  rfcn := arcsin;
  cfcn := carcsin;
  rdom := rdom_arcsin;
end;

{ FCN_arccos }

procedure FCN_arccos.InitNode;
const
  rdom_arccos: TSDD = (a: -1; b: 1; Kind: sddBii; Complement: False);
begin
  inherited;
  rfcn := arccos;
  cfcn := carccos;
  rdom := rdom_arccos;
end;

{ FCN_arctan }

procedure FCN_arctan.InitNode;
begin
  rfcn := arctan;
  cfcn := carctan;
end;

{ FCN_arccot }

procedure FCN_arccot.InitNode;
begin
  rfcn := arccot;
  cfcn := carccot;
end;

{ FCN_arcsec }

procedure FCN_arcsec.InitNode;
const
  rdom_arcsec: TSDD = (a: -1; b: 1; Kind: sddBee; Complement: True);
begin
  rfcn := arcsec;
  cfcn := carcsec;
  rdom := rdom_arcsec;
end;

{ FCN_arccsc }

procedure FCN_arccsc.InitNode;
const
  rdom_arccsc: TSDD = (a: -1; b: 1; Kind: sddBee; Complement: True);
begin
  rfcn := arccsc;
  cfcn := carccsc;
  rdom := rdom_arccsc;
end;

{ FCN_sinh }

procedure FCN_sinh.InitNode;
begin
  rfcn := sinh;
  cfcn := csinh;
end;

{ FCN_cosh }

procedure FCN_cosh.InitNode;
begin
  rfcn := cosh;
  cfcn := ccosh;
end;

{ FCN_tanh }

procedure FCN_tanh.InitNode;
begin
  rfcn := Math.tanh;
  cfcn := ctanh;
end;

{ FCN_coth }

procedure FCN_coth.InitNode;
begin
  rfcn := Math.coth;
  cfcn := ccoth;
end;

{ FCN_sech }

procedure FCN_sech.InitNode;
begin
  rfcn := ASNum.sech;
  cfcn := csech;
end;

{ FCN_csch }

procedure FCN_csch.InitNode;
begin
  rfcn := ASNum.csch;
  cfcn := ccsch;
end;

{ FCN_arcsinh }

procedure FCN_arcsinh.InitNode;
begin
  rfcn := ASNum.arcsinh;
  cfcn := carcsinh;
end;

{ FCN_arccosh }

procedure FCN_arccosh.InitNode;
const
  rdom_arccosh: TSDD = (a: 1; Kind: sddGeq; Complement: False);
begin
  inherited;
  rfcn := arccosh;
  cfcn := carccosh;
  rdom := rdom_arccosh;
end;

{ FCN_arctanh }

procedure FCN_arctanh.InitNode;
const
  rdom_arctanh: TSDD = (a: -1; b: 1; Kind: sddBee; Complement: False);
begin
  inherited;
  rfcn := arctanh;
  cfcn := carctanh;
  rdom := rdom_arctanh;
end;

{ FCN_arccoth }

procedure FCN_arccoth.InitNode;
const
  rdom_arccoth: TSDD = (a: -1; b: 1; Kind: sddBii; Complement: True);
begin
  inherited;
  rfcn := arccoth;
  cfcn := carccoth;
  rdom := rdom_arccoth;
end;

{ FCN_arcsech }

procedure FCN_arcsech.InitNode;
const
  rdom_arcsech: TSDD = (a: 0; b: 1; Kind: sddBei; Complement: False);
begin
  inherited;
  rfcn := arcsech;
  cfcn := carcsech;
  rdom := rdom_arcsech;
end;

{ FCN_arccsch }

procedure FCN_arccsch.InitNode;
begin
  rfcn := ASNum.arccsch;
  cfcn := carccsch;
end;

{ FCN_sinc }

procedure FCN_sinc.InitNode;
begin
  rfcn := sinc;
  cfcn := csinc;
end;

{ FCN_exp }

procedure FCN_exp.InitNode;
begin
  rfcn := exp;
  cfcn := cexp;
end;

{ FCN_ln }

procedure FCN_ln.InitNode;
const
  rdom_ln: TSDD = (a: 0; Kind: sddGt; Complement: False);
begin
  inherited;
  rfcn := ln;
  cfcn := cln;
  rdom := rdom_ln;
end;

{ FCN_log }

procedure FCN_log.InitNode;
const
  rdom_ln: TSDD = (a: 0; Kind: sddGt; Complement: False);
begin
  inherited;
  rfcn := Log10;
  cfcn := clog;
  rdom := rdom_ln;
end;

{ FCN_Floor }

procedure FCN_Floor.SimpleFunction;
var
  X: TASR;
begin
  inherited;
  Args.Extract(X).Close;
  Result := ASOInt(ASNum.Floor64(X));
end;

{ FCN_Ceil }

procedure FCN_Ceil.SimpleFunction;
var
  X: TASR;
begin
  Args.Extract(X).Close;
  Result := ASOInt(ASNum.Ceil64(X));
end;

{ FCN_Round }

procedure FCN_Round.SimpleFunction;
var
  X: TASR;
begin
  Args.Extract(X).Close;
  Result := ASOInt(Round(X));
end;

{ FCN_Trunc }

procedure FCN_Trunc.SimpleFunction;
var
  X: TASR;
begin
  Args.Extract(X).Close;
  Result := ASOInt(Trunc(X));
end;

{ FCN_Frac }

procedure FCN_Frac.InitNode;
begin
  rfcn := frac;
end;

{ FCN_Sgn }

procedure FCN_Sgn.SimpleFunction;
var
  x: TASR;
  z: TASC;
begin
  if Args.PeekAt(0) is TAlgosimComplexNumber then
  begin
    Args.Extract(z).Close;
    Result := ASO(csign(z));
  end
  else
  begin
    Args.Extract(x).Close;
    Result := ASOInt(Sign(x));
  end;
end;

{ FCN_mod }

procedure FCN_mod.SimpleFunction;
var
  A, B: TASI;
  X, Y: TASR;
begin
  if (Args.PeekAt(0) is TAlgosimInteger) and (Args.PeekAt(1) is TAlgosimInteger) then
  begin
    Args.Extract(A).Extract(B).Close;
    Result := ASOInt(ASNum.imod(A, B));
  end
  else
  begin
    Args.Extract(X).Extract(Y).Close;
    Result := ASO(ASNum.rmod(X, Y));
  end;
end;

{ FCN_lcm }

procedure FCN_lcm.SimpleFunction;
var
  Vals: TArray<Int64>;
begin
  Vals := Args.ExtractInt64s;
  Result := ASOInt(ASNum.lcm(Vals));
end;

{ FCN_gcd }

procedure FCN_gcd.SimpleFunction;
var
  Vals: TArray<Int64>;
begin
  Vals := Args.ExtractInt64s;
  Result := ASOInt(ASNum.gcd(Vals));
end;

{ FCN_combinations }

procedure FCN_combinations.SimpleFunction;
var
  n, k: Integer;
  res: TASI;
begin
  Args.Extract(n).Extract(k).Close;
  res := intcombinations(n, k);
  if res <> 0 then
    Result := ASOInt(res)
  else
    Result := ASO(combinations(n, k));
end;

{ FCN_permutations }

procedure FCN_permutations.SimpleFunction;
var
  n, k: Integer;
  res: TASI;
begin
  Args.Extract(n).Extract(k).Close;
  res := intpermutations(n, k);
  if res <> 0 then
    Result := ASOInt(res)
  else
    Result := ASO(permutations(n, k));
end;

{ FCN_IsPrime }

procedure FCN_IsPrime.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := ASO(ASNum.IsPrime(Arg));
end;

{ FCN_NextPrime }

procedure FCN_NextPrime.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := ASOInt(ASNum.NextPrime(Arg));
end;

{ FCN_PrevPrime }

procedure FCN_PrevPrime.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := ASOInt(ASNum.PreviousPrime(Arg));
end;

{ FCN_NthPrime }

procedure FCN_NthPrime.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  if Arg < 0 then
    Arg := 0
  else if Arg > Integer.MaxValue then
  begin
    Result := ASO(failure, 'Cannot test integers this large for primality.');
    Exit;
  end;
  Result := ASOInt(ASNum.NthPrime(Integer(Arg)));
end;

{ FCN_PrimePi }

procedure FCN_PrimePi.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  if Arg < 0 then
    Result := ASOInt(0)
  else if Arg > Integer.MaxValue then
    Result := ASO(failure, 'Cannot test integers this large for primality.')
  else
    Result := ASOInt(ASNum.PrimePi(Arg));
end;

{ FCN_Fibonacci }

procedure FCN_Fibonacci.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  if InRange(Arg, Low(IntFibonaccis), High(IntFibonaccis)) then
    Result := ASOInt(IntFibonaccis[Arg])
  else
    Result := ASO(ASNum.Fibonacci(Arg));
end;

{ FCN_Lucas }

procedure FCN_Lucas.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  if InRange(Arg, Low(IntLucas), High(IntLucas)) then
    Result := ASOInt(IntLucas[Arg])
  else
    Result := ASO(ASNum.Lucas(Arg));
end;

{ FCN_MöbiusMu }

procedure FCN_MöbiusMu.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := ASOInt(ASNum.MöbiusMu(Arg));
end;

{ FCN_Mertens }

procedure FCN_Mertens.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := ASOInt(ASNum.Mertens(Arg));
end;

{ FCN_AreCoprime }

procedure FCN_AreCoprime.SimpleFunction;
var
  Arg1, Arg2: TASI;
begin
  Args.Extract(Arg1).Extract(Arg2).Close;
  Result := ASO(ASNum.coprime(Arg1, Arg2));
end;

{ FCN_Iverson }

procedure FCN_Iverson.SimpleFunction;
var
  Arg: Boolean;
begin
  Args.Extract(Arg).Close;
  Result := ASOInt(ASNum.IversonBracket(Arg));
end;

{ FCN_Kronecker }

procedure FCN_Kronecker.SimpleFunction;
var
  Arg1, Arg2: TASI;
begin
  Args.Extract(Arg1).Extract(Arg2).Close;
  Result := ASOInt(ASNum.KroneckerDelta(Arg1, Arg2));
end;

{ FCN_LegendreSymbol }

procedure FCN_LegendreSymbol.SimpleFunction;
var
  Arg1, Arg2: TASI;
begin
  Args.Extract(Arg1).Extract(Arg2).Close;
  Result := ASOInt(ASNum.LegendreSymbol(Arg1, Arg2));
end;

{ FCN_JacobiSymbol }

procedure FCN_JacobiSymbol.SimpleFunction;
var
  Arg1, Arg2: TASI;
begin
  Args.Extract(Arg1).Extract(Arg2).Close;
  Result := ASOInt(ASNum.JacobiSymbol(Arg1, Arg2));
end;

{ FCN_KroneckerSymbol }

procedure FCN_KroneckerSymbol.SimpleFunction;
var
  Arg1, Arg2: TASI;
begin
  Args.Extract(Arg1).Extract(Arg2).Close;
  Result := ASOInt(ASNum.KroneckerSymbol(Arg1, Arg2));
end;

{ FCN_totient }

procedure FCN_totient.SimpleFunction;
var
  Arg: Integer;
begin
  Args.Extract(Arg).Close;
  Result := ASOInt(ASNum.totient(Arg));
end;

{ FCN_cototient }

procedure FCN_cototient.SimpleFunction;
var
  Arg: Integer;
begin
  Args.Extract(Arg).Close;
  Result := ASOInt(ASNum.cototient(Arg));
end;

{ FCN_PrimeFactors }

procedure FCN_PrimeFactors.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := TAlgosimArray.CreateWithValue(ASNum.PrimeFactors(Arg));
end;

{ FCN_Radical }

procedure FCN_Radical.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := ASOInt(ASNum.Radical(Arg));
end;

{ FCN_IsSquareFree }

procedure FCN_IsSquareFree.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := ASO(ASNum.IsSquareFree(Arg));
end;

{ FCN_Factorize }

procedure FCN_Factorize.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := TAlgosimArray.CreateWithValue(ASNum.factorize(Arg));
end;

{ FCN_FactorizedExpression }

procedure FCN_FactorizedExpression.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := ASO(ASNum.GetFactorizedString(Arg, True));
end;

{ FCN_Divisors }

procedure FCN_Divisors.SimpleFunction;
var
  Arg: TASI;
begin
  Args.Extract(Arg).Close;
  Result := TAlgosimArray.CreateWithValue(ASNum.divisors(Arg));
end;

{ FCN_ContinuedFraction }

procedure FCN_ContinuedFraction.SimpleFunction;
var
  Arg: TAlgosimObject;
  maxlen: Integer;
  cf: TArray<TASI>;
begin

  Args.Extract(Arg).ExtractPos(maxlen, 18).Close;
  if Arg is TAlgosimRationalNumber then
    cf := ASNum.ContinuedFraction(TAlgosimRationalNumber(Arg).Value)
  else if stRationalNumber.MatchingName(Arg) then
    cf := ASNum.ContinuedFraction(ASOToRationalNumber(TAlgosimTypedStructure(Arg)))
  else if Arg is TAlgosimInteger then
    cf := [Arg.ToASI]
  else if Arg is TAlgosimNumber then
    cf := ASNum.ContinuedFraction(Arg.ToASR, maxlen)
  else
    ErrInvalidArguments;

  if Length(cf) > maxlen then
    SetLength(cf, maxlen);

  Result := TAlgosimArray.CreateWithValue(cf);

end;

{ FCN_ToFraction }

procedure FCN_ToFraction.SimpleFunction;
var
  RatParts: TAlgosimTypedStructure;
  Num: TAlgosimNumber;
  CF: TArray<TASI>;
begin

  if (Args.Count <= 1) and not (Args.PeekAt(0) is TAlgosimArray) then
  begin
    if Args.PeekAt(0) is TAlgosimStructure then
    begin
      Args.Extract(RatParts, stRationalNumber);
      Result := ASORat(ASOToRationalNumber(RatParts));
    end
    else
    begin
      Args.Extract(Num);
      Result := ASORat(Num.ToRat);
    end;
  end

  else
  begin
    CF := Args.ExtractInt64s;
    Result := ASORat(ASNum.ContinuedFractionToFraction(CF));
  end;

  if Result is TAlgosimRationalNumber then
  begin
    TAlgosimRationalNumber(Result).NumberFormat := nfFraction;
    TAlgosimRationalNumber(Result).NumberFormatOverride := True;
  end;

end;

{ FCN_ToSymbolicForm }

procedure FCN_ToSymbolicForm.SimpleFunction;
resourcestring
  SNoCloseEnoughSymbolicFormFound = 'No close enough symbolic form found.';

  function GetStr(const AValue: TASR): string;
  var
    SSF: TSimpleSymbolicForm;
  begin
    SSF := ASNum.ToSymbolicForm(AValue);
    if SSF.valid then
      Result := SSF.ToString(Context.FormatOptions)
    else
      Result := SNoCloseEnoughSymbolicFormFound;
  end;

var
  Arg: TAlgosimNumber;
  z: TASC;
begin
  Args.Extract(Arg).Close;
  if Arg.IsComplex then
  begin
    z := Arg.ToASC;
    Result := TAlgosimStructure.CreateWithValue(
      ['Re', 'Im'],
      [ASO(GetStr(z.Re)), ASO(GetStr(z.Im))]
    );
  end
  else
    Result := ASO(GetStr(Arg.ToASR));
end;

{ FCN_erf }

procedure FCN_erf.InitNode;
begin
  rfcn := ASNum.erf;
end;

{ FCN_cerf }

procedure FCN_erfc.InitNode;
begin
  rfcn := ASNum.erfc;
end;

{ FCN_FresnelC }

procedure FCN_FresnelC.InitNode;
begin
  rfcn := ASNum.FresnelC;
end;

{ FCN_FresnelS }

procedure FCN_FresnelS.InitNode;
begin
  rfcn := ASNum.FresnelS;
end;

{ FCN_Si }

procedure FCN_Si.InitNode;
begin
  rfcn := ASNum.Si;
end;

{ FCN_Ci }

procedure FCN_Ci.InitNode;
begin
  rfcn := ASNum.Ci;
end;

{ FCN_Bessel }

procedure FCN_Bessel.SimpleFunction;
var
  N: Integer;
  Arg: TAlgosimNumber;
begin

  Args.Extract(N).Extract(Arg).Close;

  if Arg.IsComplex then
    Result := ASO(ASNum.Bessel(N, Arg.ToASC))
  else
    Result := ASO(ASNum.Bessel(N, Arg.ToASR));

end;

{ FCN_Laguerre }

procedure FCN_Laguerre.SimpleFunction;
var
  N: Integer;
  Arg: TAlgosimNumber;
begin

  Args.Extract(N).Extract(Arg).Close;

  if Arg.IsComplex then
    Result := ASO(ASNum.Laguerre(N, Arg.ToASC))
  else
    Result := ASO(ASNum.Laguerre(N, ARg.ToASR));

end;

{ FCN_Hermite }

procedure FCN_Hermite.SimpleFunction;
var
  N: Integer;
  Arg: TAlgosimNumber;
begin

  Args.Extract(N).Extract(Arg).Close;

  if Arg.IsComplex then
    Result := ASO(ASNum.Hermite(N, Arg.ToASC))
  else
    Result := ASO(ASNum.Hermite(N, Arg.ToASR));

end;

{ FCN_Legendre }

procedure FCN_Legendre.SimpleFunction;
var
  N: Integer;
  Arg: TAlgosimNumber;
begin

  Args.Extract(N).Extract(Arg).Close;

  if Arg.IsComplex then
    Result := ASO(ASNum.Legendre(N, Arg.ToASC))
  else
    Result := ASO(ASNum.Legendre(N, Arg.ToASR));

end;

{ FCN_GammaFunction }

procedure FCN_GammaFunction.InitNode;
begin
  rfcn := ASNum.GammaFunction;
  cfcn := ASNum.GammaFunction;
end;

{ FCN_Chebyshev }

procedure FCN_Chebyshev.SimpleFunction;
var
  N: Integer;
  Arg: TAlgosimNumber;
begin

  Args.Extract(N).Extract(Arg).Close;

  if Arg.IsComplex then
    Result := ASO(ASNum.Chebyshev(N, Arg.ToASC))
  else
    Result := ASO(ASNum.Chebyshev(N, Arg.ToASR));

end;

{ FCN_Bernstein }

procedure FCN_Bernstein.SimpleFunction;
var
  I, N: Integer;
  Arg: TAlgosimNumber;
begin

  Args.Extract(I).Extract(N).Extract(Arg).Close;

  if Arg.IsComplex then
    Result := ASO(ASNum.Bernstein(I, N, Arg.ToASC))
  else
    Result := ASO(ASNum.Bernstein(I, N, Arg.ToASR));

end;

{ FCN_HarmonicNumber }

procedure FCN_HarmonicNumber.SimpleFunction;
var
  Arg: TAlgosimNumber;
  IntVal: TASI;
  X: TASR;
begin
  Args.Extract(Arg).Close;
  if Arg.TryToASI(IntVal) then
    Result := ASO(ASNum.HarmonicNumber(IntVal))
  else
  begin
    X := Arg.ToASR;
    if X > TASI.MaxValue then
      Result := ASO(EulerMascheroni + Ln(X))
    else
      ErrInvalidArguments;
  end;
end;

{ FCN_And }

procedure FCN_And.DoBitwise;
var
  i: Integer;
  Res, Operand: TAlgosimInteger;
begin
  if not EvalChildren(1) then Exit; // 0 already evaluated
  Res := TAlgosimInteger.Create(Children[0].Value);
  Value := Res;
  for i := 1 to ChildCount - 1 do
  begin
    Extract<TAlgosimInteger>(i, Operand);
    Res.Value := Res.Value and Operand.Value;
  end;
end;

procedure FCN_And.DoExecute;
var
  i, h: Integer;
  Operand: TAlgosimBoolean;
begin

  h := Args.Count - 1;

  for i := 0 to h do
  begin

    if not EvalChild(i) then Exit;

    // Bitwise?
    if (i = 0) and (Args.PeekAt(0) is TAlgosimInteger) then
    begin
      DoBitwise;
      Exit;
    end;

    Extract<TAlgosimBoolean>(i, Operand);

    if not Operand.Value or (i = h) then
    begin
      TMover<TAlgosimObject>.Move(Value, Children[i].Value);
      Exit;
    end;

  end;

  Result := ASO(True);

end;

{ FCN_Or }

procedure FCN_Or.DoBitwise;
var
  i: Integer;
  Res, Operand: TAlgosimInteger;
begin
  if not EvalChildren(1) then Exit; // 0 already evaluated
  Res := TAlgosimInteger.Create(Children[0].Value);
  Value := Res;
  for i := 1 to ChildCount - 1 do
  begin
    Extract<TAlgosimInteger>(i, Operand);
    Res.Value := Res.Value or Operand.Value;
  end;
end;

procedure FCN_Or.DoExecute;
var
  i, h: Integer;
  Operand: TAlgosimBoolean;
begin

  h := Args.Count - 1;

  for i := 0 to h do
  begin

    if not EvalChild(i) then Exit;

    // Bitwise?
    if (i = 0) and (Args.PeekAt(0) is TAlgosimInteger) then
    begin
      DoBitwise;
      Exit;
    end;

    Extract<TAlgosimBoolean>(i, Operand);

    if Operand.Value or (i = h) then
    begin
      TMover<TAlgosimObject>.Move(Value, Children[i].Value);
      Exit;
    end;

  end;

  Result := ASO(False);

end;

{ FCN_Not }

procedure FCN_Not.SimpleFunction;
var
  Arg: Boolean;
  IntArg: TASI;
begin
  if Args.PeekAt(0) is TAlgosimInteger then
  begin
    Args.Extract(IntArg).Close;
    Result := ASOInt(not IntArg);
    Exit;
  end;
  Args.Extract(Arg).Close;
  Result := ASO(not Arg);
end;

{ FCN_Xor }

procedure FCN_Xor.SimpleFunction;
var
  Left, Right: Boolean;
  LInt, RInt: TASI;
begin
  // Bitwise?
  if Args.PeekAt(0) is TAlgosimInteger then
  begin
    Args.Extract(LInt).Extract(RInt).Close;
    Result := ASOInt(LInt xor RInt);
    Exit;
  end;
  Args.Extract(Left).Extract(Right).Close;
  Result := ASO(Left xor Right);
end;

{ FCN_Nand }

procedure FCN_Nand.SimpleFunction;
var
  Left, Right: Boolean;
begin
  Args.Extract(Left).Extract(Right).Close;
  Result := ASO(not (Left and Right));
end;

{ FCN_Nor }

procedure FCN_Nor.SimpleFunction;
var
  Left, Right: Boolean;
begin
  Args.Extract(Left).Extract(Right).Close;
  Result := ASO(not (Left or Right));
end;

{ FCN_ImpliesRight }

procedure FCN_ImpliesRight.SimpleFunction;
var
  Left, Right: Boolean;
begin
  Args.Extract(Left).Extract(Right).Close;
  Result := ASO(not Left or Right);
end;

{ FCN_ImpliesLeft }

procedure FCN_ImpliesLeft.SimpleFunction;
var
  Left, Right: Boolean;
begin
  Args.Extract(Left).Extract(Right).Close;
  Result := ASO(not Right or Left);
end;

{ FCN_Equivalent }

procedure FCN_Equivalent.SimpleFunction;
var
  Left, Right: Boolean;
begin
  Args.Extract(Left).Extract(Right).Close;
  Result := ASO(Left = Right);
end;

{ FCN_Equals }

procedure FCN_Equals.SimpleFunction;
var
  Arg1, Arg2: TAlgosimObject;
  LArgs: TArgumentExtractor;
  PrevObj, Obj: TAlgosimObject;
begin

  if Args.Count <> 2 then
  begin
    LArgs := Self.Args;
    if LArgs.ArgExists then
      LArgs := LArgs.Extract(PrevObj);
    while LArgs.ArgExists do
    begin
      LArgs := LArgs.Extract(Obj);
      if not PrevObj.Equals(Obj) then
      begin
        Result := ASO(False);
        Exit;
      end;
      PrevObj := Obj;
    end;
    Result := ASO(True);
    Exit;
  end;

  Args.Extract(Arg1).Extract(Arg2).Close;
  Result := ASO(Arg1.Equals(Arg2));

end;

{ FCN_NotEquals }

procedure FCN_NotEquals.SimpleFunction;
var
  Arg1, Arg2: TAlgosimObject;
begin
  Args.Extract(Arg1).Extract(Arg2).Close;
  Result := ASO(not Arg1.Equals(Arg2));
end;

{ FCN_LessThan }

procedure FCN_LessThan.SimpleFunction;
var
  Arg1, Arg2: TAlgosimObject;
  LArgs: TArgumentExtractor;
  PrevNum, Num: TAlgosimNumber;
begin

  if Args.Count <> 2 then
  begin
    LArgs := Self.Args;
    if LArgs.ArgExists then
      LArgs := LArgs.Extract(PrevNum);
    while LArgs.ArgExists do
    begin
      LArgs := LArgs.Extract(Num);
      if not TAlgosimNumber.LessThan(PrevNum, Num) then
      begin
        Result := ASO(False);
        Exit;
      end;
      PrevNum := Num;
    end;
    Result := ASO(True);
    Exit;
  end;

  Args.Extract(Arg1).Extract(Arg2).Close;

  if (Arg1 is TAlgosimNumber) and (Arg2 is TAlgosimNumber) then
    Result := ASO(TAlgosimNumber.LessThan(TAlgosimNumber(Arg1), TAlgosimNumber(Arg2)))

  else if (Arg1 is TAlgosimRealVector) and (Arg2 is TAlgosimRealVector) then
    Result := ASO(TAlgosimRealVector(Arg1).Value < TAlgosimRealVector(Arg2).Value)

  else if (Arg1 is TAlgosimRealMatrix) and (Arg2 is TAlgosimRealMatrix) then
    Result := ASO(TAlgosimRealMatrix(Arg1).Value < TAlgosimRealMatrix(Arg2).Value)

  else if IsTypedStructure(Arg1, [stDate, stDateTime]) and IsTypedStructure(Arg2, [stDate, stDateTime]) then
    Result :=
      ASO(
        CompareDateTime(
          ASOToDateTime(Arg1),
          ASOToDateTime(Arg2)
        ) = LessThanValue
      )

  else
    ErrInvalidArguments;

end;

{ FCN_LessThanOrEqualTo }

procedure FCN_LessThanOrEqualTo.SimpleFunction;
var
  Arg1, Arg2: TAlgosimObject;
  LArgs: TArgumentExtractor;
  PrevNum, Num: TAlgosimNumber;
begin

  if Args.Count <> 2 then
  begin
    LArgs := Self.Args;
    if LArgs.ArgExists then
      LArgs := LArgs.Extract(PrevNum);
    while LArgs.ArgExists do
    begin
      LArgs := LArgs.Extract(Num);
      if not TAlgosimNumber.LessThanOrEqualTo(PrevNum, Num) then
      begin
        Result := ASO(False);
        Exit;
      end;
      PrevNum := Num;
    end;
    Result := ASO(True);
    Exit;
  end;

  Args.Extract(Arg1).Extract(Arg2).Close;

  if (Arg1 is TAlgosimNumber) and (Arg2 is TAlgosimNumber) then
    Result := ASO(TAlgosimNumber.LessThanOrEqualTo(TAlgosimNumber(Arg1), TAlgosimNumber(Arg2)))

  else if (Arg1 is TAlgosimRealVector) and (Arg2 is TAlgosimRealVector) then
    Result := ASO(TAlgosimRealVector(Arg1).Value <= TAlgosimRealVector(Arg2).Value)

  else if (Arg1 is TAlgosimRealMatrix) and (Arg2 is TAlgosimRealMatrix) then
    Result := ASO(TAlgosimRealMatrix(Arg1).Value <= TAlgosimRealMatrix(Arg2).Value)

  else if IsTypedStructure(Arg1, [stDate, stDateTime]) and IsTypedStructure(Arg2, [stDate, stDateTime]) then
    Result :=
      ASO(
        CompareDateTime(
          ASOToDateTime(Arg1),
          ASOToDateTime(Arg2)
        ) <= EqualsValue
      )

  else
    ErrInvalidArguments;

end;

{ FCN_GreaterThan }

procedure FCN_GreaterThan.SimpleFunction;
var
  Arg1, Arg2: TAlgosimObject;
  IntVal: Integer;
  LArgs: TArgumentExtractor;
  PrevNum, Num: TAlgosimNumber;
begin

  if Args.Count <> 2 then
  begin
    LArgs := Self.Args;
    if LArgs.ArgExists then
      LArgs := LArgs.Extract(PrevNum);
    while LArgs.ArgExists do
    begin
      LArgs := LArgs.Extract(Num);
      if not TAlgosimNumber.GreaterThan(PrevNum, Num) then
      begin
        Result := ASO(False);
        Exit;
      end;
      PrevNum := Num;
    end;
    Result := ASO(True);
    Exit;
  end;

  Args.Extract(Arg1).Extract(Arg2).Close;

  if (Arg1 is TAlgosimNumber) and (Arg2 is TAlgosimNumber) then
    Result := ASO(TAlgosimNumber.GreaterThan(TAlgosimNumber(Arg1), TAlgosimNumber(Arg2)))

  else if (Arg1 is TAlgosimRealVector) and (Arg2 is TAlgosimRealVector) then
    Result := ASO(TAlgosimRealVector(Arg1).Value > TAlgosimRealVector(Arg2).Value)

  else if (Arg1 is TAlgosimRealVector) and (Arg2 is TAlgosimNumber) and Arg2.TryToInt32(IntVal) and (IntVal = 0) then
    Result := ASO(TAlgosimRealVector(Arg1).Value.IsPositive)

  else if (Arg1 is TAlgosimRealMatrix) and (Arg2 is TAlgosimRealMatrix) then
    Result := ASO(TAlgosimRealMatrix(Arg1).Value > TAlgosimRealMatrix(Arg2).Value)

  else if (Arg1 is TAlgosimRealMatrix) and (Arg2 is TAlgosimNumber) and Arg2.TryToInt32(IntVal) and (IntVal = 0) then
    Result := ASO(TAlgosimRealMatrix(Arg1).Value.IsPositive)

  else if IsTypedStructure(Arg1, [stDate, stDateTime]) and IsTypedStructure(Arg2, [stDate, stDateTime]) then
    Result :=
      ASO(
        CompareDateTime(
          ASOToDateTime(Arg1),
          ASOToDateTime(Arg2)
        ) = GreaterThanValue
      )

  else
    ErrInvalidArguments;

end;

{ FCN_GreaterThanOrEqualTo }

procedure FCN_GreaterThanOrEqualTo.SimpleFunction;
var
  Arg1, Arg2: TAlgosimObject;
  IntVal: Integer;
  LArgs: TArgumentExtractor;
  PrevNum, Num: TAlgosimNumber;
begin

  if Args.Count <> 2 then
  begin
    LArgs := Self.Args;
    if LArgs.ArgExists then
      LArgs := LArgs.Extract(PrevNum);
    while LArgs.ArgExists do
    begin
      LArgs := LArgs.Extract(Num);
      if not TAlgosimNumber.GreaterThanOrEqualTo(PrevNum, Num) then
      begin
        Result := ASO(False);
        Exit;
      end;
      PrevNum := Num;
    end;
    Result := ASO(True);
    Exit;
  end;

  Args.Extract(Arg1).Extract(Arg2).Close;

  if (Arg1 is TAlgosimNumber) and (Arg2 is TAlgosimNumber) then
    Result := ASO(TAlgosimNumber.GreaterThanOrEqualTo(TAlgosimNumber(Arg1), TAlgosimNumber(Arg2)))

  else if (Arg1 is TAlgosimRealVector) and (Arg2 is TAlgosimRealVector) then
    Result := ASO(TAlgosimRealVector(Arg1).Value >= TAlgosimRealVector(Arg2).Value)

  else if (Arg1 is TAlgosimRealVector) and (Arg2 is TAlgosimNumber) and Arg2.TryToInt32(IntVal) and (IntVal = 0) then
    Result := ASO(TAlgosimRealVector(Arg1).Value.IsNonNegative)

  else if (Arg1 is TAlgosimRealMatrix) and (Arg2 is TAlgosimRealMatrix) then
    Result := ASO(TAlgosimRealMatrix(Arg1).Value >= TAlgosimRealMatrix(Arg2).Value)

  else if (Arg1 is TAlgosimRealMatrix) and (Arg2 is TAlgosimNumber) and Arg2.TryToInt32(IntVal) and (IntVal = 0) then
    Result := ASO(TAlgosimRealMatrix(Arg1).Value.IsNonNegative)

  else if IsTypedStructure(Arg1, [stDate, stDateTime]) and IsTypedStructure(Arg2, [stDate, stDateTime]) then
    Result :=
      ASO(
        CompareDateTime(
          ASOToDateTime(Arg1),
          ASOToDateTime(Arg2)
        ) >= EqualsValue
      )

  else
    ErrInvalidArguments;

end;

{ FCN_Dim }

procedure FCN_Dim.DoExecute;
var
  Arg: TAlgosimVector;
begin
  CheckNumArgs(1);
  if not ExtractRef<TAlgosimVector>(0, Arg) then Exit;
  Result := ASOInt(Arg.Dimension);
end;

{ FCN_Size }

procedure FCN_Size.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASOSize(Arg.PlanarExtent);
end;

{ FCN_Width }

procedure FCN_Width.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASOInt(Arg.PlanarExtent.cx);
end;

{ FCN_Height }

procedure FCN_Height.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASOInt(Arg.PlanarExtent.cy);
end;

{ FCN_Subscript }

function FCN_Subscript.BuildLValue(LValueData: TLValueData): Boolean;
var
  i: Integer;
begin
  Result := ChildCount >= 2;
  if Result then
  begin
    for i := 1 to ChildCount - 1 do
    begin
      Children[i].Evaluate;
      if IsControl(Children[i].Value) then
        Exit(False);
    end;
    if ChildCount = 2 then
      LValueData.Add(TLValuePathItem.Create(Children[1].Value))
    else
    begin
      // emulate an array of integers, so you can write A[1, 2] instead of A['(1, 2)]
      FreeAndNil(FEquivArray);
      FEquivArray := TAlgosimArray.Create;
      for i := 1 to ChildCount - 1 do
        FEquivArray.Add(Children[i].Value.Clone);
      LValueData.Add(TLValuePathItem.Create(FEquivArray));
    end;
    Result := Children[0].BuildLValue(LValueData);
  end;
end;

destructor FCN_Subscript.Destroy;
begin
  FreeAndNil(FEquivArray);
  inherited;
end;

procedure FCN_subscript.DoExecute;
var
  Obj, Idx: TAlgosimObject;
begin
  CheckNumArgsAtLeast(2);
  if not ExtractRef(0, Obj) then Exit;
  if not EvalChildren(1) then Exit;
  if Args.Count = 2 then
  begin
    Args.Skip.Extract(Idx);
    Result := Obj.GetSubscriptedValue(TSubscript.Create(Idx));
  end
  else
  begin
    // emulate an array of integers, so you can write A[1, 2] instead of A['(1, 2)]
    Idx := TAlgosimArray.CreateWithValue(Args.Skip.ExtractInt64s);
    try
      Result := Obj.GetSubscriptedValue(TSubscript.Create(Idx));
    finally
      Idx.Free;
    end;
  end;
end;

function FCN_Subscript.LValuePart: Boolean;
begin
  Result := True;
end;

{ FCN_AccessMember }

function FCN_AccessMember.BuildLValue(LValueData: TLValueData): Boolean;
begin
  Result := (ChildCount = 2) and IsSymbol(Children[1]);
  if Result then
  begin
    LValueData.Add(TLValuePathItem.Create(TASSymbolExprNode(Children[1]).Symbol));
    Result := Children[0].BuildLValue(LValueData);
  end;
end;

procedure FCN_AccessMember.DoExecute;
var
  Struct: TAlgosimStructure;
  MbrName: string;
begin

  CheckNumArgs(2);

  if not TryLValueFetch then
  begin
    if not EvalChild(0) then Exit;
    CheckSymbol(1);
    Args.Extract(Struct);
    MbrName := TASSymbolExprNode(Children[1]).Symbol;
    Result := Struct[MbrName];
    Struct.Release(MbrName);
  end;

end;

function FCN_AccessMember.LValuePart: Boolean;
begin
  Result := True;
end;

{ FCN_norm }

procedure FCN_Norm.SimpleFunction;
var
  Arg: TAlgosimNumericEntity;
  Kind: string;
  Param: Integer;
begin
  Args.Extract(Arg).Extract(Kind, 'Euclidean').Extract(Param, 2).Close;
  Result := ASO(Arg.Norm(TNormType.FromString(Kind), Param, QuitPauseCheck));
end;

{ FCN_NormSquared }

procedure FCN_NormSquared.SimpleFunction;
var
  Arg: TAlgosimNumericEntity;
begin
  Args.Extract(Arg).Close;
  Result := Arg.NormSquared;
end;

{ FCN_Normalized }

procedure FCN_Normalized.SimpleFunction;
var
  Arg: TAlgosimVector;
begin
  Args.Extract(Arg).Close;
  Result := Arg.NormalizedIfNonzero;
end;

{ FCN_First }

function FCN_First.BuildLValue(LValueData: TLValueData): Boolean;
begin
  Result := ChildCount = 1;
  if Result then
  begin
    LValueData.Add(TLValuePathItem.Create(skFirst));
    Result := Children[0].BuildLValue(LValueData);
  end;
end;

procedure FCN_First.DoExecute;
var
  Obj: TAlgosimObject;
  N: Integer;
begin

  CheckNumArgs([1, 2]);

  if Args.Count = 1 then
  begin
    if not ExtractRef(0, Obj) then Exit;
    Result := Obj.Values[1];
  end
  else
  begin
    if not EvalChild(1) then Exit;
    Args.Skip.ExtractNonNeg(N).Close;

    if TryExtractStoreRef(0, Obj) then
      Result := Obj.First(N) // don't modify!
    else
    begin
      if not EvalChild(0) then Exit;
      if Args.PeekAt(0).IsPlanarContainer then
        Result := Args.PeekAt(0).First(N)
      else
      begin
        Args.MoveObject(Value);
        Value.Truncate(N);
      end;
    end;
  end;

end;

function FCN_First.LValuePart: Boolean;
begin
  Result := True;
end;

{ FCN_Last }

function FCN_Last.BuildLValue(LValueData: TLValueData): Boolean;
begin
  Result := ChildCount = 1;
  if Result then
  begin
    LValueData.Add(TLValuePathItem.Create(skLast));
    Result := Children[0].BuildLValue(LValueData);
  end;
end;

procedure FCN_Last.DoExecute;
var
  Obj: TAlgosimObject;
  N: Integer;
begin

  CheckNumArgs([1, 2]);

  if Args.Count = 1 then
  begin
    if not ExtractRef(0, Obj) then Exit;
    Result := Obj.Values[-1];
  end
  else
  begin
    if not EvalChild(1) then Exit;
    Args.Skip.ExtractNonNeg(N).Close;

    if TryExtractStoreRef(0, Obj) then
      Result := Obj.Last(N) // don't modify!
    else
    begin
      if not EvalChild(0) then Exit;
      if Args.PeekAt(0).IsPlanarContainer then
        Result := Args.PeekAt(0).Last(N)
      else
      begin
        Args.MoveObject(Value);
        Value.RemoveFirst(Value.ValueCount - N);
      end;
    end;
  end;

end;

function FCN_Last.LValuePart: Boolean;
begin
  Result := True;
end;

{ FCN_Part }

procedure FCN_Part.DoExecute;
var
  Obj: TAlgosimObject;
  Ranges, Ranges2: TArray<TRange>;
begin

  CheckNumArgs([2, 3]);
  if not ExtractRef(0, Obj) then Exit;
  if not EvalChildren(1) then Exit;

  case Args.Count - 1 of
    1:
      begin
        Args.Skip.Extract(Ranges).Close;
        Result := Obj.Part(Ranges)
      end;
    2:
      begin
        Args.Skip.Extract(Ranges).Extract(Ranges2).Close;
        Result := Obj.Part2d(Ranges, Ranges2);
      end;
  else
    ErrInvalidArguments;
  end;

end;

{ FCN_Range }

procedure FCN_Range.SimpleFunction;
var
  From, &To, Step: Integer;
begin
  Args.Extract(From).Extract(&To, From).Extract(Step, 1).Close;
  Result := ASOIntRange(From, &To, Step);
end;

{ FCN_Sort }

procedure FCN_Sort.ChooseComparer(const AStr: string);
begin
  if AStr = 'standard order' then
    rcmp := TASRComparer.StandardOrder
  else if AStr = 'standard order descending' then
    rcmp := TASRComparer.StandardOrderDescending
  else if AStr = 'absolute value' then
    rcmp := TASRComparer.AbsoluteValue
  else if AStr = 'absolute value descending' then
    rcmp := TASRComparer.AbsoluteValueDescending
  else if AStr = 'real and imaginary parts' then
    ccmp := TASCComparer.ReIm
  else if AStr = 'real and imaginary parts descending' then
    ccmp := TASCComparer.ReImDescending
  else if AStr = 'modulus' then
    ccmp := TASCComparer.Modulus
  else if AStr = 'modulus descending' then
    ccmp := TASCComparer.ModulusDescending
  else if AStr = 'argument' then
    ccmp := TASCComparer.Argument
  else if AStr = 'argument descending' then
    ccmp := TASCComparer.ArgumentDescending
  else if AStr = 'modulus argument' then
    ccmp := TASCComparer.ModulusArgument
  else if AStr = 'modulus argument descending' then
    ccmp := TASCComparer.ModulusArgumentDescending
  else
    raise EInvArgs.CreateFmt(SUnknownComparer, [AStr]);
end;

procedure FCN_Sort.SimpleFunction;
var
  CmpName: string;
begin
  Args.MoveObject(Value).Extract(CmpName, '').Close;
  if CmpName.IsEmpty then
  begin
    if asoComplex in Value.ClassFlags then
      raise Exception.Create('No comparison method specified.')
    else
      Value.Sort
  end
  else
  begin
    ChooseComparer(CmpName.ToLower);
    if Assigned(ccmp) then
      Value.Sort(ccmp)
    else if Assigned(rcmp) then
      Value.Sort(rcmp)
    else
      ErrInternal;
  end;
end;

{ FCN_CustomSort }

procedure FCN_CustomSort.DoExecute;
var
  SymLeft, SymRight: TList<TASExprNode>;
begin

  CheckNumArgs(2);

  if not EvalChild(0) then Exit;
  Args.MoveObject(Value);

  SymLeft := TList<TASExprNode>.Create;
  try
    SymRight := TList<TASExprNode>.Create;
    try

      FindSymbols(Children[1], 'left', SymLeft);
      FindSymbols(Children[1], 'right', SymRight);

      Value.SafeSort(TComparer<TAlgosimObject>.Construct(
        function(const Left, Right: TAlgosimObject): Integer
        var
          res: TAlgosimObject;
          cmpres: TASR;
        begin
          PopulateSymbols(SymLeft, Left.Clone);
          PopulateSymbols(SymRight, Right.Clone);
          Children[1].Evaluate;
          res := Children[1].Value;
          CheckFailure(res);
          if res is TAlgosimInteger then
            Result := Sign(TAlgosimInteger(res).Value)
          else if (res is TAlgosimNumber) and res.TryToASR(cmpres) then
            Result := Sign(cmpres)
          else
            raise EAlgosimObjectException.CreateFmt(SComparerDidntReturnReal, [res.TypeName]);
        end
        ));

    finally
      SymRight.Free;
    end;
  finally
    SymLeft.Free;
  end;

end;

{ FCN_Shuffle }

procedure FCN_Shuffle.SimpleFunction;
begin
  Args.MoveObject<TAlgosimObject>(Value).Close;
  Result.Shuffle;
end;

{ FCN_Reverse }

procedure FCN_Reverse.SimpleFunction;
begin
  Args.MoveObject<TAlgosimObject>(Value).Close;
  Result.Reverse;
end;

{ FCN_Unique }

procedure FCN_Unique.SimpleFunction;
var
  Obj: TAlgosimObject;
  Eps: TASR;
begin
  CheckNumArgs([1, 2]);
  case Args.Count of
    1:
      begin
        Args.Extract(Obj).Close;
        Result := Obj.RemoveDuplicates;
      end;
    2:
      begin
        Args.Extract(Obj).ExtractNonNeg(Eps).Close;
        Result := Obj.RemoveDuplicatesEps(Eps);
      end;
  else
    ErrInvalidArguments;
  end;
end;

{ FCN_AdjUnique }

procedure FCN_AdjUnique.SimpleFunction;
var
  Obj: TAlgosimObject;
  Eps: TASR;
begin
  CheckNumArgs([1, 2]);
  case Args.Count of
    1:
      begin
        Args.Extract(Obj).Close;
        Result := Obj.RemoveAdjacentDuplicates;
      end;
    2:
      begin
        Args.Extract(Obj).ExtractNonNeg(Eps).Close;
        Result := Obj.RemoveAdjacentDuplicatesEps(Eps);
      end;
  else
    ErrInvalidArguments;
  end;
end;

{ FCN_Frequencies }

procedure FCN_Frequencies.SimpleFunction;
var
  Obj: TAlgosimObject;
  Eps: TASR;
begin
  CheckNumArgs([1, 2]);
  case Args.Count of
    1:
      begin
        Args.Extract(Obj).Close;
        Result := Obj.Frequencies;
      end;
    2:
      begin
        Args.Extract(Obj).ExtractNonNeg(Eps).Close;
        Result := Obj.FrequenciesEps(Eps);
      end;
  else
    ErrInvalidArguments;
  end;
end;

{ FCN_CollapseSequences }

procedure FCN_CollapseSequences.SimpleFunction;
var
  Obj: TAlgosimObject;
  Eps: TASR;
begin
  CheckNumArgs([1, 2]);
  case Args.Count of
    1:
      begin
        Args.Extract(Obj).Close;
        Result := Obj.CollapseSequences;
      end;
    2:
      begin
        Args.Extract(Obj).ExtractNonNeg(Eps).Close;
        Result := Obj.CollapseSequencesEps(Eps);
      end;
  else
    ErrInvalidArguments;
  end;
end;

{ FCN_ZeroVector }

procedure FCN_ZeroVector.SimpleFunction;
var
  Dim: Integer;
begin
  Args.ExtractPos(Dim).Close;
  Result := ASO(ZeroVector(Dim));
end;

{ FCN_ComplexZeroVector }

procedure FCN_ComplexZeroVector.SimpleFunction;
var
  Dim: Integer;
begin
  Args.ExtractPos(Dim).Close;
  Result := ASO(ComplexZeroVector(Dim));
end;

{ FCN_RandomVector }

procedure FCN_RandomVector.SimpleFunction;
var
  Dim: Integer;
begin
  Args.ExtractPos(Dim).Close;
  Result := ASO(RandomVector(Dim));
end;

{ FCN_RandomIntVector }

procedure FCN_RandomIntVector.SimpleFunction;
var
  Dim, A, B: Integer;
begin
  Args.ExtractPos(Dim).Extract(A).Extract(B).Close;
  if A >= B then
    raise EInvArgs.Create('The set of possible values is empty.');
  Result := ASO(RandomIntVector(Dim, A, B));
end;

{ FCN_RandomSignedVector }

procedure FCN_RandomSignedVector.SimpleFunction;
var
  Dim: Integer;
begin
  Args.ExtractPos(Dim).Close;
  Result := ASO(RandomVectorWithSigns(Dim));
end;

{ FCN_BasisVector }

procedure FCN_BasisVector.SimpleFunction;
var
  Dim, Index: Integer;
begin
  Args.ExtractPos(Dim).ExtractPos(Index).Close;
  Result := ASO(UnitVector(Dim, Index - 1));
end;

{ FCN_SequenceVector }

procedure FCN_SequenceVector.SimpleFunction;
var
  Start, &End, Step: Integer;
  A: TArray<TASI>;
begin

  if Args.Count = 1 then
  begin
    Start := 1;
    Args.ExtractPos(&End).Close;
    A := CreateIntSequence64(Start, &End);
  end
  else
  begin
    Args.Extract(Start).Extract(&End).ExtractPos(Step, 1).Close;
    A := CreateIntSequence64(Start, &End, Step);
  end;

  Result := ASO(TRealVector.Create(Int64ArrToRealArr(A)));

end;

{ FCN_SequenceList }

procedure FCN_SequenceList.SimpleFunction;
var
  Start, &End, Step: Integer;
  A: TArray<TASI>;
begin

  if Args.Count = 1 then
  begin
    Start := 1;
    Args.ExtractPos(&End).Close;
    A := CreateIntSequence64(Start, &End);
  end
  else
  begin
    Args.Extract(Start).Extract(&End).ExtractPos(Step, 1).Close;
    A := CreateIntSequence64(Start, &End, Step);
  end;

  Result := TAlgosimArray.CreateWithValue(A);

end;

{ TIntervalFunction }

procedure TIntervalFunction.SimpleFunction;
var
  a, b, b′, δ, t: TASR;
  L: TList<TASR>;
begin

  Args.Extract(a).Extract(b).ExtractPos(δ, 0).Close;

  if (a > b) or (a = b) and Openinterval then
  begin
    Result := TAlgosimArray.Create;
    Exit;
  end;

  if a = b then
  begin
    Result := TAlgosimArray.CreateWithValue([a]);
    Exit;
  end;

  if δ = 0 then
    δ := (b - a) / 1000;

  if OpenInterval then
  begin
    a := a + δ;
    b := b - δ;
  end;

  L := TList<TASR>.Create;
  try
    L.Capacity := Trunc((b - a) / δ) + 1;
    t := a;
    b′ := b + δ / 1000;    
    while t <= b′ do
    begin    
      L.Add(t);
      t := t + δ;
    end;
    if (L.Count > 0) and (L.Last > b) then
      L[L.Count - 1] := b;
    Result := TAlgosimArray.CreateWithValue(L.ToArray);
  finally
    L.Free;
  end;
  
end;

{ FCN_ClosedInterval }

procedure FCN_ClosedInterval.InitNode;
begin
  inherited;
  OpenInterval := False;
end;


{ FCN_OpenInterval }

procedure FCN_OpenInterval.InitNode;
begin
  inherited;
  OpenInterval := True;
end;

{ FCN_Random }

function FCN_Random.BuildLValue(LValueData: TLValueData): Boolean;
begin
  Result := ChildCount = 1;
  if Result then
  begin
    LValueData.Add(TLValuePathItem.Create(skRandom));
    Result := Children[0].BuildLValue(LValueData);
  end;
end;

procedure FCN_Random.DoExecute;
var
  Obj: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Obj) then Exit;
  Result := Obj.Random;
end;

function FCN_Random.LValuePart: Boolean;
begin
  Result := True;
end;

{ FCN_RandomInt }

procedure FCN_RandomInt.SimpleFunction;
var
  A, B: Integer;
begin

  if Args.Count = 1 then
  begin
    Args.ExtractPos(A).Close;
    Result := ASOInt(System.Random(A));
  end
  else
  begin
    Args.Extract(A).Extract(B).Close;
    if A >= B then
      raise EInvArgs.Create('The set of possible values is empty.');
    Result := ASOInt(RandomRange(A, B));
  end;

end;

{ FCN_RandomReal }

procedure FCN_RandomReal.SimpleFunction;
var
  A, B: TASR;
begin

  if Args.Count = 0 then
    Result := ASO(System.Random)
  else if Args.Count = 1 then
  begin
    Args.Extract(A).Close;
    Result := ASO(A * System.Random);
  end
  else
  begin
    Args.Extract(A).Extract(B).Close;
    Result := ASO(A + (B - A) * System.Random);
  end;

end;

{ FCN_SetRandomSeed }

procedure FCN_SetRandomSeed.SimpleFunction;
var
  Arg: Integer;
begin
  Args.Extract(Arg).Close;
  RandSeed := Arg;
  Result := ASO(success);
end;

{ FCN_Randomize }

procedure FCN_Randomize.SimpleFunction;
begin
  Args.Close;
  Randomize;
  Result := ASO(success);
end;

{ TASContainerFunction }

function __max_int(const A, B: TASI): TASI;
begin
  if A > B then
    Result := A
  else
    Result := B;
end;

function __min_int(const A, B: TASI): TASI;
begin
  if A < B then
    Result := A
  else
    Result := B;
end;

function __max_float(const A, B: TASR): TASR;
begin
  if A > B then
    Result := A
  else
    Result := B;
end;

function __min_float(const A, B: TASR): TASR;
begin
  if A < B then
    Result := A
  else
    Result := B;
end;

procedure TASContainerFunction.DoExecute;
const
  ARG_INDEX_EXPRESSION = 0;
  ARG_INDEX_SYMBOL = 1;
  ARG_INDEX_LOWER_BOUND = 2;
  ARG_INDEX_UPPER_BOUND = 3;
var
  i: Integer;
  k, m, n: TASI;
  Obj: TAlgosimObject;
  symbol: string;
  symbols: TList<TASExprNode>;
  list: TAlgosimArray;
  x, y: TASR;
  ifcn: function(const A, B: TASI): TASI;
  rfcn: function(const A, B: TASR): TASR;
begin

  CheckNumArgs([1, 2, 4]);

  if Args.Count = 1 then
  begin
    if not ExtractRef(0, Obj) then Exit;
    fcn(Obj);
  end

  else if (Args.Count = 2) and ((Self is FCN_Min) or (Self is FCN_Max)) then // special case: allow min(x, y) and max(x, y)
  begin

    if not EvalChildren then Exit;

    if Self is FCN_Min then
    begin
      ifcn := __min_int;
      rfcn := __min_float;
    end
    else if Self is FCN_Max then
    begin
      ifcn := __max_int;
      rfcn := __max_float;
    end
    else
      ErrInternal;

    if (Args.PeekAt(0) is TAlgosimInteger) and (Args.PeekAt(1) is TAlgosimInteger) then
    begin
      Args.Extract(m).Extract(n).Close;
      Result := ASOInt(ifcn(m, n));
    end
    else
    begin
      Args.Extract(x).Extract(y).Close;
      Result := ASO(rfcn(x, y));
    end;

  end

  else if Args.Count = 4 then
  begin

    for i := ARG_INDEX_LOWER_BOUND to ARG_INDEX_UPPER_BOUND do
      if not EvalChild(i) then Exit;

    Args.Skip.Skip.Extract(m).Extract(n).Close;

    CheckSymbol(ARG_INDEX_SYMBOL);
    symbol := TASSymbolExprNode(Children[ARG_INDEX_SYMBOL]).Symbol;

    symbols := TList<TASExprNode>.Create;
    try
      FindSymbols(Self.Children[ARG_INDEX_EXPRESSION], symbol, symbols);
      list := TAlgosimArray.Create;
      try
        if n - m + 1 > Integer.MaxValue then
          raise Exception.Create('Too many values for the index variable.');
        list.Capacity := Max(0, n - m + 1);
        for k := m to n do
        begin
          PopulateSymbols(symbols, ASOInt(k));
          Children[ARG_INDEX_EXPRESSION].Evaluate;
          if IsControl(Children[ARG_INDEX_EXPRESSION].Value) then
          begin
            TMover<TAlgosimObject>.Move(Value, Children[ARG_INDEX_EXPRESSION].Value);
            Exit;
          end;
          list.Add(Children[ARG_INDEX_EXPRESSION].Value.Clone);
        end;
        fcn(list);
      finally
        list.Free;
      end;
    finally
      symbols.Free;
    end;

  end

  else
    ErrInvalidArguments;

end;

{ FCN_Sum }

procedure FCN_Sum.fcn(AObject: TAlgosimObject);
begin
  Result := AObject.N_sum;
end;

{ FCN_Product }

procedure FCN_Product.fcn(AObject: TAlgosimObject);
begin
  Result := AObject.N_product;
end;

{ FCN_Min }

procedure FCN_Min.fcn(AObject: TAlgosimObject);
begin
  Result := AObject.N_min;
end;

{ FCN_Max }

procedure FCN_Max.fcn(AObject: TAlgosimObject);
begin
  Result := AObject.N_max;
end;

{ FCN_ArithmeticMean }

procedure FCN_ArithmeticMean.fcn(AObject: TAlgosimObject);
begin
  Result := AObject.N_ArithmeticMean;
end;

{ FCN_GeometricMean }

procedure FCN_GeometricMean.fcn(AObject: TAlgosimObject);
begin
  Result := AObject.N_GeometricMean;
end;

{ FCN_HarmonicMean }

procedure FCN_HarmonicMean.fcn(AObject: TAlgosimObject);
begin
  Result := AObject.N_HarmonicMean;
end;

{ TASContainerPredicateFunction }

procedure TASContainerPredicateFunction.DoExecute;
var
  Obj: TAlgosimObject;
  Predicate: TAlgosimFunctionObject;
begin
  CheckNumArgs(2);
  if not ExtractRef(0, Obj) then Exit;
  if not EvalChild(1) then Exit;
  Args(1).Extract(Predicate);
  fcn(Obj,
    function(AObject: TAlgosimObject): Boolean
    var
      res: TAlgosimObject;
    begin
      res := Predicate.Execute(Context, [AObject], False);
      try
        if res is TAlgosimBoolean then
          Result := TAlgosimBoolean(res).Value
        else
          raise EAlgosimObjectException.CreateFmt(SPredicateDidntReturnBool, [res.TypeName]);
      finally
        res.Free;
      end;
    end);
end;

{ FCN_Count }

procedure FCN_Count.DoExecute;
var
  Obj, Value: TAlgosimObject;
  Predicate: TAlgosimFunctionObject;
  Eps: TASR;
begin

  CheckNumArgs([2, 3]);
  if not ExtractRef(0, Obj) then Exit;
  if not EvalChildren(1) then Exit;

  if Args.PeekAt(1) is TAlgosimFunctionObject then
  begin
    Args.Skip.Extract(Predicate).Close;
    Result := ASOInt(Obj.Count(
      function(AObject: TAlgosimObject): Boolean
      var
        res: TAlgosimObject;
      begin
        res := Predicate.Execute(Context, [AObject], False);
        try
          if res is TAlgosimBoolean then
            Result := TAlgosimBoolean(res).Value
          else
            raise EAlgosimObjectException.CreateFmt(SPredicateDidntReturnBool, [res.TypeName]);
        finally
          res.Free;
        end;
      end
    ))
  end
  else
  begin
    case Args.Count of
      2:
        begin
          Args.Skip.Extract(Value).Close;
          Result := ASOInt(Obj.CountValue(Value));
        end;
      3:
        begin
          Args.Skip.Extract(Value).ExtractNonNeg(Eps).Close;
          Result := ASOInt(Obj.CountValueEps(Value, Eps));
        end;
    else
      ErrInvalidArguments;
    end;
  end;

end;

{ FCN_Contains }

procedure FCN_Contains.DoExecute;
var
  Obj, Value: TAlgosimObject;
  Eps: TASR;
begin
  CheckNumArgs([2, 3]);
  if not ExtractRef(0, Obj) then Exit;
  if not EvalChildren(1) then Exit;
  case Args.Count of
    2:
      begin
        Args.Skip.Extract(Value).Close;
        Result := ASO(Obj.Contains(Value));
      end;
    3:
      begin
        Args.Skip.Extract(Value).ExtractNonNeg(Eps).Close;
        Result := ASO(Obj.ContainsEps(Value, Eps));
      end;
  else
    ErrInvalidArguments;
  end;
end;

{ FCN_Exists }

procedure FCN_Exists.fcn(AObject: TAlgosimObject;
  APred: TASOPredicate);
begin
  Result := ASO(AObject.Exists(APred));
end;

{ FCN_ExistsUnique }

procedure FCN_ExistsUnique.fcn(AObject: TAlgosimObject;
  APred: TASOPredicate);
begin
  Result := ASO(AObject.ExistsUnique(APred));
end;

{ FCN_ForAll }

procedure FCN_ForAll.fcn(AObject: TAlgosimObject;
  APred: TASOPredicate);
begin
  Result := ASO(AObject.ForAll(APred));
end;

{ FCN_IndicesOf }

procedure FCN_IndicesOf.DoExecute;
var
  Obj, Value: TAlgosimObject;
  Predicate: TAlgosimFunctionObject;
  Eps: TASR;
begin

  CheckNumArgs([2, 3]);
  if not ExtractRef(0, Obj) then Exit;
  if not EvalChildren(1) then Exit;

  if Args.PeekAt(1) is TAlgosimFunctionObject then
  begin
    Args.Skip.Extract(Predicate).Close;
    Result := Obj.IndicesOf(
      function(AObject: TAlgosimObject): Boolean
      var
        res: TAlgosimObject;
      begin
        res := Predicate.Execute(Context, [AObject], False);
        try
          if res is TAlgosimBoolean then
            Result := TAlgosimBoolean(res).Value
          else
            raise EAlgosimObjectException.CreateFmt(SPredicateDidntReturnBool, [res.TypeName]);
        finally
          res.Free;
        end;
      end
    )
  end
  else
  begin
    case Args.Count of
      2:
        begin
          Args.Skip.Extract(Value).Close;
          Result := Obj.IndicesOfValue(Value);
        end;
      3:
        begin
          Args.Skip.Extract(Value).ExtractNonNeg(Eps).Close;
          Result := Obj.IndicesOfValueEps(Value, Eps);
        end;
    else
      ErrInvalidArguments;
    end;
  end;

end;

{ FCN_Filter }

procedure FCN_Filter.fcn(AObject: TAlgosimObject;
  APred: TASOPredicate);
begin
  Result := AObject.Filter(APred);
end;

{ FCN_Pick }

procedure FCN_Pick.DoExecute;
var
  Obj: TAlgosimObject;
  Predicate: TAlgosimFunctionObject;
  Level: Integer;
begin
  CheckNumArgs([2, 3]);
  if not ExtractRef(0, Obj) then Exit;
  if not EvalChildren(1) then Exit;
  Args
    .Skip
    .Extract(Predicate)
    .ExtractPos(Level, 1)
    .Close;
  Value := Obj.Pick(
    function(AObject: TAlgosimObject): Boolean
    var
      res: TAlgosimObject;
    begin
      res := Predicate.Execute(Context, [AObject], False);
      try
        if res is TAlgosimBoolean then
          Result := TAlgosimBoolean(res).Value
        else
          raise EAlgosimObjectException.CreateFmt(SPredicateDidntReturnBool, [res.TypeName]);
      finally
        res.Free;
      end;
    end,
    Level);
end;

{ FCN_PickRecursive }

procedure FCN_PickRecursive.fcn(AObject: TAlgosimObject;
  APred: TASOPredicate);
begin
  Result := AObject.PickRecursive(APred);
end;

{ FCN_Apply }

procedure FCN_Apply.SimpleFunction;
var
  Fcn: TAlgosimFunctionObject;
  Level: Integer;
  &Set: TAlgosimSet;
  i: Integer;
begin

  if Args.PeekAt(0) is TAlgosimSet then
  begin
    // sets don't support the Apply method (cannot simply replace
    // elements in-place: that might create a set with duplicate elements)
    Args.Extract(&Set).Extract(Fcn).Close; // for sets, we don't support the Level argument for simplicity (again, by altering the set's elements, the parent set might end up with duplicate elements)
    Result := TAlgosimSet.Create;
    Result.Capacity := &Set.Capacity;
    for i := 1 to &Set.ElementCount do
      Result.AddElement(Fcn.Execute(Context, [&Set.Elements[i]], False));
    Exit;
  end;

  Args.MoveObject(Value).Extract(Fcn).ExtractPos(Level, 1).Close;
  Value.Apply(
    function(AObject: TAlgosimObject): TAlgosimObject
    begin
      Result := Fcn.Execute(Context, [AObject], False);
    end,
    nil,
    Level
  );

end;

{ FCN_ApplyIf }

procedure FCN_ApplyIf.SimpleFunction;
var
  Pred, Fcn: TAlgosimFunctionObject;
  Level: Integer;
begin
  Args.MoveObject(Value).Extract(Pred).Extract(Fcn).ExtractPos(Level, 1).Close;
  Value.Apply(
    function(AObject: TAlgosimObject): TAlgosimObject
    begin
      Result := Fcn.Execute(Context, [AObject], False);
    end,
    function(AObject: TAlgosimObject): Boolean
    var
      res: TAlgosimObject;
    begin
      res := Pred.Execute(Context, [AObject], False);
      try
        if res is TAlgosimBoolean then
          Result := TAlgosimBoolean(res).Value
        else
          raise EAlgosimObjectException.CreateFmt(SPredicateDidntReturnBool, [res.TypeName]);
      finally
        res.Free;
      end;
    end,
    Level
  );
end;

{ FCN_ReplaceAll }

procedure FCN_ReplaceAll.SimpleFunction;
var
  OldVal, NewVal: TAlgosimObject;
  Level: Integer;
begin
  Args
    .MoveObject(Value)
    .Extract(OldVal)
    .Extract(NewVal)
    .ExtractPos(Level, 1)
    .Close;
  Value.Replace(OldVal, NewVal, Level);
end;

{ FCN_ReplaceIf }

procedure FCN_ReplaceIf.SimpleFunction;
var
  NewVal: TAlgosimObject;
  Pred: TAlgosimFunctionObject;
  Level: Integer;
begin
  Args
    .MoveObject(Value)
    .Extract(Pred)
    .Extract(NewVal)
    .ExtractPos(Level, 1)
    .Close;
  Value.Replace(
    function(AObject: TAlgosimObject): Boolean
    var
      res: TAlgosimObject;
    begin
      res := Pred.Execute(Context, [AObject], False);
      try
        if res is TAlgosimBoolean then
          Result := TAlgosimBoolean(res).Value
        else
          raise EAlgosimObjectException.CreateFmt(SPredicateDidntReturnBool, [res.TypeName]);
      finally
        res.Free;
      end;
    end,
    NewVal,
    Level);
end;

{ FCN_ReplaceEvery }

procedure FCN_ReplaceEvery.SimpleFunction;
var
  NewVal: TAlgosimObject;
  Level: Integer;
begin
  Args
    .MoveObject(Value)
    .Extract(NewVal)
    .ExtractPos(Level, 1)
    .Close;
  Value.Replace(NewVal, Level);
end;

{ FCN_RemoveAll }

procedure FCN_RemoveAll.SimpleFunction;
var
  OldVal: TAlgosimObject;
  Level: Integer;
begin
  Args
    .MoveObject(Value)
    .Extract(OldVal)
    .ExtractPos(Level, 1)
    .Close;
  Value.RemoveAll(OldVal, Level);
end;

{ FCN_RemoveIf }

procedure FCN_RemoveIf.SimpleFunction;
var
  Pred: TAlgosimFunctionObject;
  Level: Integer;
  &Set: TAlgosimSet;
  i: Integer;
  res: TAlgosimObject;
begin

  if Args.PeekAt(0) is TAlgosimSet then
  begin

    // sets don't support the Remove method

    Args.Extract(&Set).Extract(Pred).Close;
    Result := TAlgosimSet.Create;
    Result.Capacity := &Set.Capacity;

    for i := 1 to &Set.ElementCount do
    begin

      res := Pred.Execute(Context, [&Set.Elements[i]], False);
      try
        if res is TAlgosimBoolean then
        begin
          if not res.ToBoolean then
            Result.AddElement(&Set.Elements[i].Clone);
        end
        else
          raise EAlgosimObjectException.CreateFmt(SPredicateDidntReturnBool, [res.TypeName]);
      finally
        res.Free;
      end;

    end;

    Exit;

  end;

  Args
    .MoveObject(Value)
    .Extract(Pred)
    .ExtractPos(Level, 1)
    .Close;
  Value.RemoveIf(
    function(AObject: TAlgosimObject): Boolean
    var
      res: TAlgosimObject;
    begin
      res := Pred.Execute(Context, [AObject], False);
      try
        if res is TAlgosimBoolean then
          Result := TAlgosimBoolean(res).Value
        else
          raise EAlgosimObjectException.CreateFmt(SPredicateDidntReturnBool, [res.TypeName]);
      finally
        res.Free;
      end;
    end,
    Level);

end;

{ FCN_RealNumber }

procedure FCN_RealNumber.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASO(Arg.ToRealNumber);
end;

{ FCN_ComplexNumber }

procedure FCN_ComplexNumber.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASO(Arg.ToComplexNumber);
end;

{ FCN_Number }

procedure FCN_Number.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := Arg.ToNumber;
end;

{ FCN_Integer }

procedure FCN_Integer.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASOInt(Arg.ToASI);
end;

{ FCN_String }

procedure FCN_String.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASO(Arg.ToString);
end;

{ FCN_RealVector }

procedure FCN_RealVector.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASO(Arg.AsRealVector);
end;

{ FCN_ComplexVector }

procedure FCN_ComplexVector.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASO(Arg.AsComplexVector);
end;

{ FCN_Vector }

procedure FCN_Vector.SimpleFunction;
var
  Arg: TAlgosimObject;
begin

  // Create a matrix
  if Args.PeekAt(0) is TAlgosimVector then
  begin

    if HasComplexArg then
      Result := ASO(TComplexMatrix.CreateFromRows(Args.ExtractComplexVectors))
    else
      Result := ASO(TRealMatrix.CreateFromRows(Args.ExtractRealVectors));

    Exit;

  end;

  // Create a vector
  case ChildCount of
    0:
      raise EAlgosimObjectException.Create(SVectDim);
    1:
      begin
        Args.Extract(Arg).Close;
        Result := Arg.AsVector;
      end;
  else
    if HasComplexArg then
      Result := ASO(TComplexVector.Create(Args.ExtractComplexNumbers))
    else
      Result := ASO(TRealVector.Create(Args.ExtractRealNumbers))
  end;

end;

{ FCN_RealMatrix }

procedure FCN_RealMatrix.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASO(Arg.AsRealMatrix);
end;

{ FCN_ComplexMatrix }

procedure FCN_ComplexMatrix.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASO(Arg.AsComplexMatrix);
end;

{ FCN_Matrix }

procedure FCN_Matrix.SimpleFunction;
var
  Arg: TAlgosimObject;
  ColCount: Integer;
  rnums: TArray<TASR>;
  cnums: TArray<TASC>;
begin

  case Args.Count of
    0:
      raise EAlgosimObjectException.Create(SMatDim);
    1:
      begin
        Args.Extract(Arg).Close;
        Result := Arg.AsMatrix;
      end;
  else

    if HasComplexArg then
    begin
      cnums := Args.ExtractPos(ColCount).ExtractComplexNumbers;
      Result := ASO(TComplexMatrix.Create(cnums, ColCount));
    end
    else
    begin
      rnums := Args.ExtractPos(ColCount).ExtractRealNumbers;
      Result := ASO(TRealMatrix.Create(rnums, ColCount));
    end;

  end;

end;

{ FCN_Boolean }

procedure FCN_Boolean.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASO(Arg.ToBoolean);
end;

{ FCN_ToList }

procedure FCN_ToList.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := Arg.ToList;
end;

{ FCN_ToSet }

procedure FCN_ToSet.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := Arg.ToSet;
end;

{ FCN_ToTable }

procedure FCN_ToTable.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := ASO(Arg.ToTable);
end;

{ FCN_BinaryData }

procedure FCN_BinaryData.SimpleFunction;
var
  Arg: TAlgosimObject;
begin
  Args.Extract(Arg).Close;
  Result := Arg.ToBinaryObject;
end;

{ FCN_MatrixFromCols }

procedure FCN_MatrixFromCols.SimpleFunction;
begin

  if HasComplexArg then
    Result := ASO(TComplexMatrix.CreateFromColumns(Args.ExtractComplexVectors))
  else
    Result := ASO(TRealMatrix.CreateFromColumns(Args.ExtractRealVectors));

end;

{ FCN_MatrixFromRows }

procedure FCN_MatrixFromRows.SimpleFunction;
begin

  if HasComplexArg then
    Result := ASO(TComplexMatrix.CreateFromRows(Args.ExtractComplexVectors))
  else
    Result := ASO(TRealMatrix.CreateFromRows(Args.ExtractRealVectors));

end;

{ FCN_MatrixFromBlocks }

procedure FCN_MatrixFromBlocks.SimpleFunction;
var
  ColCount: Integer;
begin

  Args.ExtractPos(ColCount);

  if HasComplexArg then
    Result := ASO(TComplexMatrix.Create(Args.Skip.ExtractComplexMatrices, ColCount))
  else
    Result := ASO(TRealMatrix.Create(Args.Skip.ExtractRealMatrices, ColCount));

end;

{ FCN_List }

procedure FCN_List.SimpleFunction;
var
  i: Integer;
  tmpobj: TAlgosimObject;
begin

  Result := TAlgosimArray.Create;
  Result.Capacity := ChildCount;
  for i := 0 to ChildCount - 1 do
  begin
    TMover<TAlgosimObject>.Move(tmpobj, Children[i].Value);
    Result.AddElement(tmpobj);
  end;

end;

{ FCN_Set }

procedure FCN_Set.SimpleFunction;
var
  i: Integer;
  tmpobj: TAlgosimObject;
begin

  Result := TAlgosimSet.Create;
  Result.Capacity := ChildCount;
  for i := 0 to ChildCount - 1 do
  begin
    TMover<TAlgosimObject>.Move(tmpobj, Children[i].Value); {noexcept}
    Result.AddElement(tmpobj);
  end;

end;

{ FCN_Union }

procedure FCN_Union.SimpleFunction;
var
  U, V: TAlgosimSet;
begin
  Args.Extract(U).Extract(V).Close;
  Result := TAlgosimSet.Union(U, V);
end;

{ FCN_Intersection }

procedure FCN_Intersection.SimpleFunction;
var
  U, V: TAlgosimSet;
begin
  Args.Extract(U).Extract(V).Close;
  Result := TAlgosimSet.Intersection(U, V);
end;

{ FCN_SetDifference }

procedure FCN_SetDifference.SimpleFunction;
var
  U, V: TAlgosimSet;
begin
  Args.Extract(U).Extract(V).Close;
  Result := TAlgosimSet.Difference(U, V);
end;

{ FCN_SymDiff }

procedure FCN_SymDiff.SimpleFunction;
var
  U, V: TAlgosimSet;
begin
  Args.Extract(U).Extract(V).Close;
  Result := TAlgosimSet.SymmetricDifference(U, V);
end;

{ FCN_Complement }

procedure FCN_Complement.SimpleFunction;
var
  Universe: TAlgosimObject;
  U: TAlgosimSet;
begin
  Args.Extract(U).Close;
  Context.GetObjRef('universe', Universe);
  if not (Universe is TAlgosimSet) then
    raise EAlgosimObjectException.CreateFmt(SUniverseNotASet, [Universe.ClassTypeName]);
  Result := TAlgosimSet.Difference(TAlgosimSet(Universe), U);
end;

{ FCN_ElementOf }

procedure FCN_ElementOf.SimpleFunction;
var
  x: TAlgosimObject;
  U: TAlgosimSet;
begin
  Args.Extract(x).Extract(U).Close;
  Result := ASO(TAlgosimSet.ElementOf(x, U));
end;

{ FCN_NotElementOf }

procedure FCN_NotElementOf.SimpleFunction;
var
  x: TAlgosimObject;
  U: TAlgosimSet;
begin
  Args.Extract(x).Extract(U).Close;
  Result := ASO(not TAlgosimSet.ElementOf(x, U));
end;

{ FCN_ContainsAsElement }

procedure FCN_ContainsAsElement.SimpleFunction;
var
  x: TAlgosimObject;
  U: TAlgosimSet;
begin
  Args.Extract(U).Extract(x).Close;
  Result := ASO(TAlgosimSet.ElementOf(x, U));
end;

{ FCN_NotContainsAsElement }

procedure FCN_NotContainsAsElement.SimpleFunction;
var
  x: TAlgosimObject;
  U: TAlgosimSet;
begin
  Args.Extract(U).Extract(x).Close;
  Result := ASO(not TAlgosimSet.ElementOf(x, U));
end;

{ FCN_Subset }

procedure FCN_Subset.SimpleFunction;
var
  U, V: TAlgosimSet;
begin
  Args.Extract(U).Extract(V).Close;
  Result := ASO(TAlgosimSet.Subset(U, V));
end;

{ FCN_ProperSubset }

procedure FCN_ProperSubset.SimpleFunction;
var
  U, V: TAlgosimSet;
begin
  Args.Extract(U).Extract(V).Close;
  Result := ASO(TAlgosimSet.ProperSubset(U, V));
end;

{ FCN_Superset }

procedure FCN_Superset.SimpleFunction;
var
  U, V: TAlgosimSet;
begin
  Args.Extract(U).Extract(V).Close;
  Result := ASO(TAlgosimSet.Subset(V, U));
end;

{ FCN_ProperSuperset }

procedure FCN_ProperSuperset.SimpleFunction;
var
  U, V: TAlgosimSet;
begin
  Args.Extract(U).Extract(V).Close;
  Result := ASO(TAlgosimSet.ProperSubset(V, U));
end;

{ FCN_TypeName }

procedure FCN_TypeName.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASO(Arg.TypeName);
end;

{ FCN_ClassTypeData }

procedure FCN_ClassTypeData.DoExecute;

{$IF SizeOf(TAlgosimObjectClassFlags) = 1}
type TClassFlagInt = UInt8;
{$ELSEIF SizeOf(TAlgosimObjectClassFlags) = 2}
type TClassFlagInt = UInt16;
{$ELSEIF SizeOf(TAlgosimObjectClassFlags) = 4}
type TClassFlagInt = UInt32;
{$ENDIF}

var
  Arg: TAlgosimObject;
begin

  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;

  with Arg.ClassData do
    Result := ASO(
      [
        sm('name', ASO(ClassTypeName)),
        sm('ClassFlags',
          ASOInt(
              {$IF Declared(TClassFlagInt)}
                TClassFlagInt(ClassFlags)
              {$ELSE}
                -1
              {$ENDIF}
            )
          ),
        sm('IsObjectContainer', ASO(asoObjectContainer in ClassFlags)),
        sm('IsValueContainer', ASO(asoValueContainer in ClassFlags)),
        sm('IsPlanarContainer', ASO(asoPlanarContainer in ClassFlags)),
        sm('IsOrderedContainer', ASO(asoOrderedContainer in ClassFlags)),
        sm('IsComplexType', ASO(asoComplex in ClassFlags))
      ]
    );

end;

{ FCN_ClassTypeName }

procedure FCN_ClassTypeName.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASO(Arg.ClassTypeName);
end;

{ FCN_HasComplexType }

procedure FCN_HasComplexType.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASO(Arg.IsComplex);
end;

{ FCN_IsObjectContainer }

procedure FCN_IsObjectContainer.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASO(Arg.IsObjectContainer);
end;

{ FCN_IsValueContainer }

procedure FCN_IsValueContainer.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASO(Arg.IsValueContainer);
end;

{ FCN_IsPlanarContainer }

procedure FCN_IsPlanarContainer.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASO(Arg.IsPlanarContainer);
end;

{ FCN_IsOrderedContainer }

procedure FCN_IsOrderedContainer.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASO(Arg.IsOrderedContainer);
end;

{ FCN_Beep }

procedure FCN_Beep.SimpleFunction;
resourcestring
  SWin32MessageBeep = 'Couldn''t produce message beep using the native OS API.';
  SWin32Beep = 'Couldn''t produce sinusoidal beep using the native OS API.';
  SBeepSoundType = 'Unsupported beep sound type: "%s"';
  SToneFrequency = 'Unsupported tone frequency: %d Hz';
  SToneDuration = 'Too long tone duration: %d ms';
var
  s: string;
  MB_const: Integer;
  res: Boolean;
  freq, dur: Integer;
begin

  CheckNumArgs([0, 1, 2]);

  case ChildCount of
    0..1:
      begin

        Args.Extract(s, 'default').Close;

        if SameText(s, 'default') then
          MB_const := MB_OK
        else if SameText(s, 'information') then
          MB_const := MB_ICONINFORMATION
        else if SameText(s, 'warning') then
          MB_const := MB_ICONWARNING
        else if SameText(s, 'error') then
          MB_const := MB_ICONERROR
        else if SameText(s, 'question') then
          MB_const := MB_ICONQUESTION
        else
          raise EInvArgs.CreateFmt(SBeepSoundType, [s]);

        res := Windows.MessageBeep(MB_const);

        if not res then
          raise EAlgosimOSError.Create(SWin32MessageBeep);

      end;

    2:
      begin

        Args.ExtractPos(freq).ExtractNonNeg(dur).Close;

        if not InRange(freq, 37, 32767) then
          raise EInvArgs.CreateFmt(SToneFrequency, [freq]);

        if dur > 30000 then
          raise EInvArgs.CreateFmt(SToneDuration, [dur]);

        res := Windows.Beep(freq, dur);

        if not res then
          raise EAlgosimOSError.Create(SWin32Beep);

      end;
  else
    ErrInvalidArguments;
  end;

  Result := ASO(null);

end;

{ FCN_Wait }

procedure FCN_Wait.SimpleFunction;
var
  Dur: TASR;
  C0, C1: UInt64;
  DurMS: Cardinal;
  SignaledObj: THandleObject;
begin

  Args.ExtractNonNeg(Dur).Close;

  if Round(1000*Dur) > DurMS.MaxValue then
    raise Exception.Create('Too large timeout.');

  DurMS := Round(1000*Dur);

  if TThread.Current.ThreadID = MainThreadID then
  begin
    Sleep(DurMS);
    Exit;
  end;

  while DurMS > 0 do
  begin
    C0 := GetTickCount64;
    case
      TEvent.WaitForMultiple(
        [Context.AbortCurrentEvent, Context.EnterPauseEvent],
        DurMS,
        False,
        SignaledObj
      )
    of
      wrSignaled:
        begin
          if SignaledObj = Context.AbortCurrentEvent then
            ManualAbort
          else if SignaledObj = Context.EnterPauseEvent then
          begin
            C1 := GetTickCount64;
            if DoPause(Context.ResumeEvent, Context.AbortCurrentEvent) = raAbort then
              ManualAbort;
            if C1 - C0 >= DurMS then
            begin
              Result := ASO(null);
              Exit;
            end
            else
              Dec(DurMS, Cardinal(C1 - C0));
          end;
        end;
      wrTimeout:
        begin
          Result := ASO(null);
          Exit;
        end
    else
      raise Exception.Create('Wait failed.');
    end;
  end;

end;

{ FCN_GetTickCount }

procedure FCN_GetTickCount.SimpleFunction;
begin
  Args.Close;
  Result := ASOInt(GetTickCount64);
end;

{ FCN_Heaviside }

procedure FCN_Heaviside.InitNode;
begin
  rfcn := ASNum.Heaviside;
end;

{ FCN_Ramp }

procedure FCN_Ramp.InitNode;
begin
  rfcn := ASNum.Ramp;
end;

{ FCN_Rect }

procedure FCN_Rect.InitNode;
begin
  rfcn := ASNum.Rectfcn;
end;

{ FCN_Tri }

procedure FCN_Tri.InitNode;
begin
  rfcn := ASNum.Tri;
end;

{ FCN_GetProperty }

procedure FCN_GetProperty.SimpleFunction;
var
  Arg: string;
begin
  Args.Extract(Arg).Close;
  Result := Context.GetPropVal(Arg);
end;

{ FCN_Integrate }

procedure FCN_Integrate.DoExecute;
resourcestring
  SIntegrandRealValued = 'Integrand must be a real-valued function.';
const
  ARG_INDEX_EXPRESSION = 0;
  ARG_INDEX_SYMBOL = 1;
  ARG_INDEX_LOWER_LIMIT = 2;
  ARG_INDEX_UPPER_LIMIT = 3;
var
  symbol: string;
  symbols: TList<TASExprNode>;
  LowerBound, UpperBound: TASR;
  IntegrationParams: TIntegrationParams;
  Δx: TASR;
begin

  CheckNumArgs([4, 5]);
  CheckSymbol(ARG_INDEX_SYMBOL);
  symbol := TASSymbolExprNode(Children[ARG_INDEX_SYMBOL]).Symbol;

  if not EvalChildren(ARG_INDEX_LOWER_LIMIT) then
    Exit;

  Args.Skip.Skip.Extract(LowerBound).Extract(UpperBound).ExtractPos(Δx, 0).Close;

  symbols := TList<TASExprNode>.Create;
  try
    FindSymbols(Children[ARG_INDEX_EXPRESSION], symbol, symbols);

    if Δx > 0 then
      IntegrationParams := TIntegrationParams.Delta(Δx)
    else
      IntegrationParams := TIntegrationParams.N(100000);

    Value := ASO
      (
        ASNum.integrate(
          function(const X: TASR): TASR
          begin
            PopulateSymbols(symbols, ASO(X));
            Children[ARG_INDEX_EXPRESSION].Evaluate;
            CheckFailure(Children[ARG_INDEX_EXPRESSION].Value);
            if not Children[ARG_INDEX_EXPRESSION].Value.TryToASR(Result) then
              raise EAlgosimObjectException.Create(SIntegrandRealValued);
          end,
          LowerBound,
          UpperBound,
          IntegrationParams
        )
      );

  finally
    symbols.Free;
  end;

end;

{ FCN_Differentiate }

procedure FCN_Differentiate.DoExecute;
const
  ARG_INDEX_EXPRESSION = 0;
  ARG_INDEX_SYMBOL = 1;
  ARG_INDEX_POINT = 2;
  ARG_INDEX_EPSILON = 3;
var
  symbol: string;
  symbols: TList<TASExprNode>;
  Point: TASR;
  Epsilon: TASR;
begin

  CheckNumArgs([3, 4]);
  CheckSymbol(ARG_INDEX_SYMBOL);
  symbol := TASSymbolExprNode(Children[ARG_INDEX_SYMBOL]).Symbol;

  if not EvalChildren(2) then Exit;
  Args.Skip.Skip.Extract(Point).ExtractNonNeg(Epsilon, 1E-6).Close;

  var a := TAlgosimObject(nil);
  var b := TAlgosimObject(nil);
  symbols := TList<TASExprNode>.Create;
  try

    FindSymbols(Children[ARG_INDEX_EXPRESSION], symbol, symbols);

    PopulateSymbols(symbols, ASO(Point + Epsilon));
    Children[ARG_INDEX_EXPRESSION].Evaluate;
    CheckFailure(Children[ARG_INDEX_EXPRESSION].Value);

    b := Children[ARG_INDEX_EXPRESSION].Value.Clone;

    PopulateSymbols(symbols, ASO(Point - Epsilon));
    Children[ARG_INDEX_EXPRESSION].Evaluate;
    CheckFailure(Children[ARG_INDEX_EXPRESSION].Value);

    a := Children[ARG_INDEX_EXPRESSION].Value.Clone;

    var DiffQuotient := TASExpression.Create(FCN_Divide);
    try
      DiffQuotient.Context := Self.Context;
      var LDifference := DiffQuotient.Root.AddChild(FCN_Subtract);
      DiffQuotient.Root.AddChild(ASO(2*Epsilon));
      LDifference.AddChild(b); b := niL;
      LDifference.AddChild(a); a := nil;
      DiffQuotient.Evaluate;
      CheckFailure(DiffQuotient.Root.Value);
      TMover<TAlgosimObject>.Move(Value, DiffQuotient.Root.Value);
    finally
      DiffQuotient.Free;
    end;

  finally
    symbols.Free;
    a.Free;
    b.Free;
  end;

end;

{ FCN_Length }

procedure FCN_Length.DoExecute;
var
  Arg: TAlgosimObject;
begin
  CheckNumArgs(1);
  if not ExtractRef(0, Arg) then Exit;
  Result := ASOInt(Arg.ValueCount);
end;

{ FCN_Pos }

procedure FCN_Pos.SimpleFunction;
var
  Str, Substr: string;
  Flags: TSysCharSet;
  SearchOptions: TStringSearchOptions;
  Offset: Integer;