AplEngine v2.0.0.0

AplEngine is a C# DLL which contains a large subset of the APL Interpreter.

You can use it in your C# projects to make it easier to convert APL functions or applications to C#.

Requirements

AplEngine requires:

  • the .Net Framework v4.0+

Limitations

The AplEngine DLL has the following limitations:

  • in general primitives and operators work on rank 3 arrays only
  • not all APL primitives and operators are included (although most are)
  • for some primitives/operators, some combination of argument types may not be supported (although most are)

The DLL is very useful when porting APL applications to C#.

Note that the C# primitives and operators have been prefixed with the letter A so that they appear grouped at the top of the Intellisense C# popup instead of scattered among other methods and property names. This makes using them much easier.

Download

Download a fully functional 30-day Trial:

Download »

Features

AplEngine contains a C# implementation of the following APL primitives and operators:

APL PrimitiveC# Method Name
∊BAEnlist
*BAExp
!BAFactorial
⍒BAGradeDn
⍋BAGradeUp
⍳BAIota
⍟BALog
-BANegate
~BANot
,BARavel
⍴BARho
?BARoll
⌽BARotate
⍕BAThorn
⍉BATranspose
A^BAAnd
A÷BADivide
A=BAEq
A≥BAGe
A>BAGt
A≤BALe
A⍟BALog
A<BALt
A⌈BAMax
A⌊BAMin
A-BAMinus
A⍲BANand
A≠BANe
A⍱BANor
A∨BAOr
A+BAPlus
A*BAPower
A|BARemainder
A×BATimes
A,B A⍪BACatenate
A/B A⌿BACompress
A↓BADrop
A∊BAEpsilon
A\BAExpand
A⍷BAFind
A[B]AIndex
A[B]←CAIndexAssign
A[B;]←CAIndexAssign
A[;B]←CAIndexAssign
A[B;C]←DAIndexAssign
A⍳BAIota
A⊃BAPick
⍴⍴BARank
A⍴BARho
A↑BATake
A~BAWithout
^/BAAndReduce
∨/BAOrReduce
⌊/BAMinReduce
⌈/BAMaxReduce
+/BAPlusReduce
×/BATimesReduce
÷/BADivideReduce
⌈\BAMaxScan
⌊\BAMinScan
+\BAPlusScan
×\BATimesScan

How to use the APLEngine DLL

To use the AplEngine DLL in a C# project:

  • add LC.AplEngine.dll to the project References
  • add a using LC.AplEngine; clause to classes using this DLL

Examples

Here are some APL expressions and their C# equivalent when using the above DLL:

Example 1

APL Expression:

      A←0 0 1 0 1 1
      B←A/⍳⍴A

C# equivalent:

bool[] A = { false, false, true, false, true, true };
int[] B = A.ACompress(A.ARho().AIota());

or:

int[] A = { 0, 0, 1, 0, 1, 1 };
int[] B = A.ACompress(A.ARho().AIota());

Note that C# always returns indices in origin 0: if for any reason you needed the indices in origin 1, you could use:

int[] A = { 0, 0, 1, 0, 1, 1 };
int[] B = A.ACompress(A.ARho().AIota()).APlus(1);

Also note that you generally need to use the C# methods in the reverse order of the APL primitives: this is logical since C# executes from left to right while APL executes from right to left.

Example 2

APL Expression:

      A←4 4⍴⍳100
      B←⍕A÷3
      B
 0.3333333333 0.6666666667 1           1.333333333
 1.666666667  2            2.333333333 2.666666667
 3            3.333333333  3.666666667 4
 4.333333333  4.666666667  5           5.333333333

C# equivalent:

int[,] A = 100.AIota().ARho(4, 4).APlus(1);
string[] B = A.ToDouble().ADivide(3).AThorn();
      B
 0.333333333333333 0.666666666666667 1                 1.333333333333333 
 1.666666666666667 2                 2.333333333333333 2.666666666666667 
 3                 3.333333333333333 3.666666666666667 4                 
 4.333333333333333 4.666666666666667 5                 5.333333333333333 

Note that by default C# uses the maximum possible printing precision (equivalent of using ⎕pp←17 in APL).

Also note that the AIota() DLL method has been applied to the 100 numeric value: this works because the DLL has been developed using the new C# 3.0 Extensions methods. Extension methods are static methods that can extend existing types.

All methods in the LescassseConsulting.AplEngine DLL are Extension methods of the standard C# classes like: bool, int, double, string, etc.

Example 3

APL Expression: Sorting indices A according to data B

      A←⍳5
      B←20 10 30 50 40
      C←A[⍋B[A]] 
      C
2 1 3 5 4

C# equivalent:

int[] A = 5.AIota();
int[] B = { 20, 10, 30, 50, 40 };
int[] C = A.AIndex(B.AIndex(A).AGradeUp());
      C
1 0 2 4 3

Remember that C# always works in 0 origin, so the fact it returns indices in origin 0 is not a problem since indexing an array by these indices will return the expected result.

Example 4

APL Expression: Sorting indices A according to data B

      A←⍳5
      B←20 10 30 50 40
      C←A[⍋B[A]] 
      C
2 1 3 5 4

C# equivalent:

int[] A = 5.AIota();
int[] B = { 20, 10, 30, 50, 40 };
int[] C = A.AIndex(B.AIndex(A).AGradeUp());
      C
1 0 2 4 3

Again .APlus(1) after AIota() should be applied to get the indices in origin 1.

Example 5

APL Expression: Index assigning selected rows in a matrix

      A←5 5⍴⍳25
      A[2 4 5;]←100×A[2 4 5;]
      A
    1    2    3    4    5
  600  700  800  900 1000
   11   12   13   14   15
 1600 1700 1800 1900 2000
 2100 2200 2300 2400 2500
 

C# equivalent:

int[,] A = 25.AIota().ARho(5,5).APlus(1);
int[] rows = {1,3,4};
A = A.AIndexAssign(rows, null, A.AIndex(rows, null).ATimes(100));
       A
    1    2    3    4    5 
  600  700  800  900 1000 
   11   12   13   14   15 
 1600 1700 1800 1900 2000 
 2100 2200 2300 2400 2500