Artem's blog

Mainly .NET (C#, ASP.NET) and my projects

Archives for C#

Release notes for SKGL Extension (2.0.5)

Development of our new Web API is going quite fast. Therefore, it is important to keep SKGL Extension up-to-date so that you can take an advantage of all new features! Today, I want to mention some of the changes that were added to SKGL Extension since 2.0.4.

Changes

  • Get Activated Machines is a new method in the Web API (see here) that allows you to get all the activated devices (machine code, IP and Time) for any given key. Note, you need to explicitly enable it as well as use your privateKey for each request. This method has the same authentication level as key generation. An example is shown below:
     [TestMethod]
     public void GetActivatedMachinesTest()
     {
         var productVal = SKGL.SKM.LoadProductVariablesFromString("{\"uid\":\"2\",\"pid\":\"3\",\"hsum\":\"751963\"}");
    
         Assert.IsNull(SKGL.SKM.GetActivatedMachines(productVal, "dawdwadwa", "MJAWL-ITPVZ-LKGAN-DLJDN"));
         var devices = SKGL.SKM.GetActivatedMachines(productVal, "8dOtQ44PdMLPLNzelOtPqVGdrQEVs36Z7aDQEKzJvt8pGYvtPx", "MJAWL-ITPVZ-LKGAN-DLJDN");
     }

    As you can see, in contrast to the classical operations such as validation and activation, pid, uid and hsum are passed in as a JSON array. I hope that all methods will work that way as soon as possible, because it is very easy to simply copy and paste from here and click on “Get C# friendly version”.

  • Load and Save Key Information to File will from now on take care of all error handling. This means that you need not to surround these method calls with a try-catch-finally. It’s great because you don’t need to worry if the stream is open during an exception.

Release notes for SKGL Extension (2.0.4)

I am happy to tell all users of SKGL Extension that there is a new version available (since the update in late January). In this post, I would like to mention some changes made to the API, a short usage tip, and then let you know how it is going to change in future.

Changes

  • Ability to sign pid, uid, activation dateBased on user feedback, the Web API now allows pid, uid and hsum to be added into the signature. This is particularly important for users that protect more than one product. Before, it was possible to use the same KeyInformation file (serialized by SaveKeyInformationToFile) to unlock other products (that used the same Public Key, i.e. by the same software vendor). For some, it worked out by specifying this information in the Notes field. This change makes it more simple. The activation date is intended for offline key validation; it’s a way to keep track the date of the last activation in order to force the user to activate the software periodically.
  • Deactivation: There is a new method that allows you to deactivate a license key. (method info, web api)
  • Optional Field: Finally you can access the optional field using .NET.  It’s a new type of method that takes in a ProductVariables object instead of separate strings for pid, uid, hsum, etc. Read more below Future ideas  (more info).
  • Machine code fix: The getEightDigitsLongHash was modified to fix a bug that generated nine digits instead of eight. Read more here.
  • Proxy: Get Parameters method allows you to specify the proxy settings.
  • Load Product Variables: A new method, LoadProductVariablesFromString allows you to load a serialized version of the ProductVariables object. Read more below Future ideas.

Usage tip

Some users have encountered problems when validating/activating keys because of a wrong code snippet (NullReferenceException). Basically, you should not check the .IsValid field as way to deduce whether the key is valid or invalid. Instead, check if the KeyInformation object is null.

SKGL.KeyInformation keyInfo = new SKGL.KeyInformation();
string machineID = SKGL.SKM.getMachineCode(SKGL.SKM.getSHA1);
keyInfo = SKGL.SKM.KeyActivation("pid", "uid", "hsum", "serialkey", "machine code");
 
if (keyInfo != null)
{
    //valid key
}
else
{
    //invalid key
}

Future ideas

As new functionality is added to the Web API,  more parameters have to be added to each method. In the long run, this is bad because it can be quite repetitive/confusing to add all the parameters all over again. My plan on how this can be resolved is by adding specialized classes, such as ProductVariables to facilitate reuse of existing variables in other methods. The goal is to make it as easy as possible to use SKGL Extension.

The Power of Finite Differences in Real World Problems

Introduction

Most of the people are certainly familiar with Calculus already from high school and the beginning of university. It is usually associated with concepts like infinitely smallbehaviour at infinity, finding the area under the graph, and finding the rate of change. It seems to be so much about infinity (which is difficult to imagine) but not that much about finite values. So why not look at finite differences instead? In this article, we are going to see how powerful the concept difference is, and how we can apply it to real world problems. First, we are going to look at how the difference can be found in a sequence. Secondly, the way we can find the next term and later on how we can get a formula to generate the nth term. Finally, we are going to use the idea of finding the nth term to find an expression of the sum.

The difference operation

It is quite intuitive, once we see a sequence, to try to find the difference between adjacent terms. If we are not satisfied, we look at the difference of the differences, and so on. Our aim now is to construct a method that will behave like we normally would in this situation. First, however, let’s look at what happens when we take the difference of each term.

\(a_0\)
\(a_1-a_0\)
\(a_1\) \(a_2-2a_1+a_0\)
\( a_2-a_1\) \(a_3-3a_2+3a_1-a_0\)
\(a_2\) \(a_3-2a_2+a_1\)
\(a_3-a_2\)
\(a_3\)

We can take the difference as many times as we like, but given that a sequence was constructed with only addition, subtraction, multiplication and division i.e. it was a polynomial, there is going to be a point when we can stop taking the difference. The important thing now to realize from this figure is that the difference expression contains the coefficients from the Pascal’s triangle. This is good if we want to take the difference many number of times. The code below utilizes this observation.

/// <summary>
/// Finds the difference between terms in a sequence. By chaging the degree, we can take difference of the differences.
/// </summary>
/// <param name="sequence">The sequence of doubles passed in as a double array.</param>
/// <param name="term">The index of the first term where the diff. should be taken. NB: As the degree increases, the smaller can the term be</param>
/// <param name="degree">The type of difference, i.e. if degree=1, the first difference is taken and if degree=2, the difference of the first difference is taken. </param>
/// <example>If the sequence is {1,2,3,4,...}, term=0, degree=1, we get 1. By changning degree=2, we get 0.</example>
/// <returns>The difference between the terms in the sequence, depending on the degree.</returns>
public static double GetDifference(double[] sequence, int term, int degree)
{
    // the pascal's triangle should be optimized. we only need half of the values

    double result = 0;

    bool evenStart = (term + degree) % 2 == 0 ? true : false;

    int j = 0;

    for (int i = term + degree; j <= degree; i--)
    {
        result += Pascal(degree, j) * sequence[i] * (evenStart ? (i % 2 == 0 ? 1 : -1) : (i % 2 == 0 ? -1 : 1));
        j++;
    }

    return result;

}

Finding the next term

Before we proceed in finding the next term and ultimately the polynomial describing the nth term, let’s focus our attention on a real world example. Say we have the sequence \(\{n^2\}\) i.e. \(1, 4, 9, 16 \dots\). We assume that we don’t know the nth term, i.e. we only know some values of the sequence. The common procedure in this case is to look at the differences, similar to the previous section. For example,

\(1\)
\(3\)
\(4\) \(2\)
\( 5\) \(0\)
\(9\) \(2\)
\(7\)
\(16\)

To be sure that we’ve found a pattern, we should end up at zero (assuming a polynomial generated the sequence). The interesting thing about this figure is that we know that each difference in the table can be expressed in terms of the difference expressions in the previous section. So, \(3=(4)-(1)\) and \(2 = (9)-2\times (4)+(1)\). This idea hints us to a possible way of finding the next term in the sequence. Since we know that the second difference \(2\) is constant, we can find an expression for the next term by some simple arithmetic. That is, \(2=a_n -2\times a_{n-1} + a_{n-2}\).  Thus we can find the nth term given the two terms before it. This is done by the following code:

/// <summary>
/// Finds the next term in the sequence, given that a pattern exist.
/// </summary>
/// <param name="sequence">The sequence of doubles passed in as a double array.</param>
/// <param name="term">If term=-1, the next term in the sequence is going to be found. By default, you don't need to change this variable.</param>
/// <returns></returns>
public static double GetNextTerm(double[] sequence, int term = -1)
{
    int constantIndex = 0;

    if (HasPattern(sequence, out constantIndex))
    {
        double constant = GetDifference(sequence, 0, constantIndex - 1);

        if (term == -1)
        {
            // have find the term to start with to figure out the n+1 term.
            term = sequence.Length - constantIndex; 
        }

        double result = 0;

        bool evenStart = (term + constantIndex - 1) % 2 == 0 ? true : false;

        int j = 1;

        result += constant;

        for (int i = term + constantIndex - 1; j <= constantIndex - 1; i--)
        {
            result += Pascal(constantIndex - 1, j) * sequence[i] * (evenStart ? (i % 2 == 0 ? 1 : -1) : (i % 2 == 0 ? -1 : 1));
            j++;
        }

        return result;
    }

    throw new Exception("The sequence does not contain a recognized pattern.");
}

Finding the expression for the nth term

This is a bit more tricky to find in contrast to what we’ve done so far. The nth term is very dependent on the number of times the difference operation has to be taken before we end up at zero. In the previous example, we had to take it three times to get to zero. The polynomial we got had the second degree. It turns out that if we had to take the difference \(n\) times to get to zero, the polynomial is of the degree \(n-1\). This is quite useful, because if we know how the polynomial looks like, the only thing we need to find are the coefficients (more in-depth tutorial).

In the sequence \(1,4,9,16\dots\), we had to take the difference three times, so the polynomial has the second degree, i.e. \(ax^2+bx+c\). We have three unknowns, so we need three data points to solve the system of equations. That is,

\(\left[ {\begin{array}{*{20}{c}} 1 & 1 & 1 & 1 \\ 4 & 2 & 1 & 4 \\ 9 & 3 & 1 & 9 \end{array}} \right]\)

When we reduce this matrix to echelon form, we get that the coefficient for \(n^2 \) is \(1\), and zero for the remaining terms. The code below does this task.

/// <summary>
/// Finds the coefficients of the nth term and returns them in a double array.  The first item in the array is of the highest power. The last term in the array is the constant term.
/// </summary>
/// <param name="sequence">The sequence of doubles passed in as a double array.</param>
/// <param name="degree">The degree value returned here is the number of times we have to take the differnce of this sequence (using GetDifference) to get the difference to be zero.</param>
/// <returns></returns>
public static double[] GetCoefficientsForNthTerm(double[] sequence, int degree)
{
    var mat = new Matrix(degree, degree + 1);

    for (int i = 0; i < degree; i++)
    {
        for (int j = 0; j <= degree; j++)
        {
            if (j == degree)
            {
                mat[i, j] = sequence[i];
            }
            else
            {
                mat[i, j] = Get.IntPower(i + 1, (short)(degree - j - 1));
            }

        }
    }

    mat.RREF();

    var output  = new double[degree];

    for (int i = 0; i <  degree ; i++)
    {
        output[i] = mat[i, degree];
    }

    return output;
    
}

The coefficients we get correspond to a term in the polynomial. For example, if we get \(3, 2, 1\), the polynomial is \(3x^2+2x+1\).

Finding the closed form for the sum

When we first think about how we can find the closed form for a sum, we might conclude that it is difficult. In Concrete Mathematics – A Foundation for Computer Science, an entire chapter (chp. 2) and a great part of other chapters is dedicated to sums, and the way we can find the anti-difference. At least, that was my thought when I got this idea. But later, an interesting thought came up to my mind, and that is to treat the sum as a sequence and the sequence as the difference of the sums’ terms. Let’s clarify this. If we have the sequence \( 1,2,3,4,\dots\), we can construct the partial sums, i.e. \(1, 1+2, 1+3+4, 1+2+3+4\), thus \(1, 3, 6, 10\). But the partial sums form a new sequence which we can analyse in a similar way. This means that can we can reuse quite a lot of code. Now, since in the original sequence \( 1,2,3,4,\dots\), we have to take the difference twice to get zero, in the new sequence \(1, 3, 6, 10\), we have to take the difference three times. The code for doing this is shorter, in contrast to the previous ones.

/// <summary>
/// Finds the coefficients of the closed form of the sum and returns them in a double array. The first item in the array is of the highest power. The last term in the array is the constant term.
/// </summary>
/// <param name="sequence">The sequence of doubles passed in as a double array.</param>
/// <param name="degree">The degree value returned here is the number of times we have to take the differnce of this sequence (using GetDifference) to get the difference to be zero.</param>
/// <returns></returns>
public static double[] GetCoefficientsForNthSum(double[] sequence, int degree)
{
    double[] partialSums = new double[sequence.Length];

    partialSums[0] = sequence[0];
    for (int i = 1; i < sequence.Length; i++)
    {
        partialSums[i] = partialSums[i - 1] + sequence[i];
    }

    return GetCoefficientsForNthTerm(partialSums, degree + 1);
}

Limitations

One of the limitations of this code/algorithm is that we can only use sequences that have been generated by a polynomial. Exponents are not allowed, although \(n^2= n\times n\), so that works. The reason is quite simple. Formally, we define difference as an operator on a function (similar to derivatives) as

\(\Delta f(x) = f(x+1) – f(x)\). Let’s say we have \(f(x)=2^x\). If we take \(\Delta(2^x)=2^{x+1}-2^x=2^x(2-1)=2^x\). Not good, no matter how many times we take the difference, we end up with the same thing we had in the beginning. This is why this particular algorithm does not work in this case. It is possible to add an extra step that checks against known sequences each time a difference is taken. This, I will do a bit later! 🙂

Source code

You can find all additional methods in the FiniteCalculus class in Mathos.Calculus (Mathos Core Library). Also, you can see this code in action here!

Mathos Parser is now an expression compiler

The requirement of performing several thousands of calculations (for example, during integration) led to the optimization with pre-scanned expressions. But the aim to make Mathos Parser even faster still remained. Now, I would like to introduce you to a new project of Mathos Project – Mathos Expression Compiler, based on the math tokenizer and parser logic of Mathos Parser.

This API allows you to parse an expression and “store” it as CIL code. Then, using ILAsm, you can generate a new assembly that will contain your expression entirely parsed. The only operation that occurs at runtime is the insertion of values into the variables that you declared and the operation on that variable value. To make it even faster, most of the calculations are already done before the runtime, for example, x+3+5 would be stored as x+8.

In this scenario, the time consideration can be important. Even if it is faster to execute CIL instructions, the compilation process can take some time. This has not been tested yet. The process is illustrated below:

a1

This is a very simplified way of looking at it but the point is to always test Mathos Parser together with Mathos Expression Compiler and make an estimate of how much time would be saved in different scenarios. It all depends on the context. But note, that

A performance hit is incurred only the first time the method is called. All subsequent calls to the method execute at the full speed of the native code because verification and compilation to native code don’t need to be performed again. //p. 12. Jeffrey Richter. CLR via C# 3rd Edition

So, if you plan to execute the function trillion times, it might be a good a idea to keep in mind the Expression Compiler as a better alternative, because at that point, the compilation time will be negligible.

Now, back to the features. It was mentioned in the beginning that it is based on the Mathos Parser. Note, in terms of features, Mathos Expression Compiler has at this point only a subset of those of Mathos Parser. At this point, you cannot have functions as sincos, and your own custom functions, but this will be changed in the nearest future.

There are also some changes to the way operators work. To declare an operator properly, you should use the variables OperatorListOperatorAction, and OperatorActionIL. Below, a simple example of addition operator:

OperatorList.Add("+"); // addition
OperatorActionIL.Add("+", "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Addition(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)");
OperatorAction.Add("+", (x, y) => x + y);

Comparison operators are a bit more tricky. An example of greater than operator is shown below:

OperatorList.Add(">"); // greater than
OperatorActionIL.Add(">", "call bool [mscorlib]System.Decimal::op_GreaterThan(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)\r\n" +
                            "brtrue.s q@\r\n" +
                            "ldc.i4.0 \r\n" +
                            "br.s p@\r\n"
                           + "q@: ldc.i4.1\r\n"
                           + "p@: nop\r\n"
                           + "call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Implicit(int32)");
OperatorAction.Add(">", (x, y) => x > y ? 1 : 0);

For those who understand IL, the @ sign might seem a bit strange. It is simply a way to tell the stack count to the if statement (in the compilation process).

When you actually generate an expression, this is how your IL code for that expression might look:

var mp = new Mathos.ILParser.ILMathParser();

mp.LocalVariables.Add("x");
mp.LocalVariables.Add("y");

string a = mp.Parse("(x(3x))");

Will return (only IL for the expression):

.maxstack 5
.locals init(valuetype [mscorlib]System.Decimal, valuetype [mscorlib]System.Decimal) 
ldc.i4 3
ldc.i4 0
ldc.i4 0
ldc.i4 0
ldc.i4 0
newobj instance void [mscorlib]System.Decimal::.ctor(int32,int32,int32,bool,uint8) 
stloc.0
ldloc.0
ldarg.0
call valuetype [mscorlib]System.Decimal [mscorlib]System.Decimal::op_Multiply(valuetype [mscorlib]System.Decimal,valuetype [mscorlib]System.Decimal)
stloc.1

ldloc.1

When you have the IL code, you should name the output executable(or dll) as MathosILParser, otherwise, you might get an error. In future, an option will be added to customize the name of the output file, but at this point, please use RegEx (or replace option) to change the MathosILParser.exe to something else (in the IL code).

Your function can later by called as shown below. Note, I am not using reflection at all.

decimal result = Mathos.ILFunction.Parse(3, 2);

I hope this short guide was helpful, even if it might be a bit messy. If you have performed any testing related to speed or if you want to show some examples, please feel free to comment or contact me.

The advantages of pre-scanned expressions

RubyInt project, or Iron Ruby Based Mathos Core Library Interpreter was one of the projects to be tested with the new parser feature, that is, pre-scanned expressions.

In the Integral approximation module, it is quite good to use pre-scanned expressions, since the expression stays the same through the entire process. The execution time improved in this case.

The integral approximation website in Mathos Laboratory (see it here) has also shown good results thanks to this optimization. In Mathos Laboratory in particular, it is important that methods are quick and use as small amount of resources as possible, because it is hosted in the Cloud.

I have performed some quick tests using an i3 processor (the methods are in changeset 37964), although I would not recommend them to draw specific conclusions (there is a random error involved so more repetitions of each test are needed). Also, the difficulty level of an expression can affect the tokenization time. The graphs are located below:

mp2

mp_separatly

One conclusion that can be drawn from this is that the optimization only gets useful when the same expression is evaluated more than 100-500 times.

Faster evaluation using a pre-scanned expression

[This article was updated to included changes in v. 1.0.7.2. Originally written for v. 1.0.7.1]

Today, I published a newer version of Mathos Parser on both CodePlex and NuGet. The release notes:

from v.1.0.7.2:

  • Force user to use ReadOnlyCollection when using a token list as a parameter.

from v. 1.0.7.1

  • Added method GetTokens
  • Changed the structure a bit. Now, the Scanner returns tokens instead of continuing with MathParserLogic. This is good if the same kind of expression is to be used many times.

But what does this really mean? Well, previous versions of the parser worked more locally, that is, once one function was executed, it triggered another function, and so on. Now, however, the Scanner (private method) returns a list of tokens instead of launching MathParserLogic directly. If you simply want to get tokens, you would have to execute the GetTokens function, as shown below:

var parser = new MathParser();
parser.LocalVariables.Add("x",10);

var list = parser.GetTokens("(3x+2)");

You can then send the tokens list into either Parse or ProgrammaticallyParse and it will parse it in the same way as if you would enter a string expression, that is:

decimal resultA = parser.Parse("(3x+2)");
decimal resultB = parser.Parse(list);

Both statements above will return 32, but there is one main difference; the execution time will be so much smaller for the second statement, where a “pre-compiled” list is being used. If it would take 100 milliseconds (ms) to find the value of the first statement, it would take approximately 9-10 ms for the second one. The ratio is 10:1.

This is great if you want to perform an operation where the same function is involved several thousands times, for example when approximating an integral.

I am currently thinking about converting math expressions into IL code, but this will happen sometime in future!

Recorded a new video about Mathos Core Library Interpreter

Creating a programming language with Mathos Parser (2)

In this article, I would like to find out whether it is possible to construct a programming language with Mathos Parser. In general, the question is if a simple expression parser has the necessary things to easily convert it into a language.

The answer is yes, but the language will be very limited if additional features are not added. The reason for this is because what most languages have in common is some sort of  user/machine interaction, while an expression parser only allows you to parse mathematical things and is not really designed to interpret how to write to a file or allocate memory.

For example, imagine you want to create something similar to if statements  and you decide to treat an if as a function. You would use following code:

parser.LocalFunctions.Add("if", x =>
{
    if (x[0] == 1)
    {
        return x[1];
    }
    else
    {
        if (x.Length == 3)
        {
            return x[2];
        }
        else
        {
            return 0;
        }
    }
});

So, if whatever we pass into the first parameter is true, the value in the second parameter will be returned. This is quite cool, but it does not allow us to return a series of statements. Instead, we could design a new kind of if statement that would, depending on the result from this if function, execute the right method. Here is how I solved it:

let a = get()               # ask for user input

if(a>3,1, 0)                # it only returns a number
1-> write It is true        # these execute something depending on result
0-> write It is false

As you can see, the if statement is still there, but there is now a feature that will interpret the result and make something happen. You can also use \n to separate between different statements and also name a collection of statements, as shown below:

# Using statements as small methods
# The first result will not use statement,
# the second one will.

notTrue : title Not true \n write Your number is smaller than five (or equal to) \n pause

write Type a number between 1-10

let b be get()

if(b>5, 1, 0)
1-> title A New title! \n write Your number is greater than five! \n pause
0-> notTrue

Note that both examples use a function get(). It can also be implemented as a function:

parser.LocalFunctions.Add("get", x =>
{
    return System.Convert.ToDecimal(Console.ReadLine());
}
);

You might have noticed the use of statements (see notTrue statement). Their role is to simulate a method. Everything you enter into a statement will not be executed until you call it, so you can insert undefined variables into a statement when you define it and later assign them with a value. I have also added commands like write, title, pause, clear and end. These are extensions to the language and are interpreted in the method below:

static void command(Mathos.Parser.MathParser parser, string input, Dictionary<string, string> statement, ref decimal lastResult)
{
    try
    {
        input = Regex.Replace(input, "#\\{.*?\\}#", ""); // Delete Comments #{Comment}#
        input = Regex.Replace(input, "#.*$", ""); // Delete Comments #Comment

        input = Regex.Replace(input, @"[0-9]+\!", new MatchEvaluator(FactorialString));

        input = Regex.Replace(input, @"^\s+", "");

        if (input != "")
        {
            if (input.StartsWith("write"))
            {
                Console.WriteLine(input.Substring(6));
            }
            else if (input.StartsWith("title"))
            {
                Console.Title = input.Substring(6);
            }
            else if (input.StartsWith ("clear"))
            {
                Console.Clear();
            }
            else
            {
                if (input.Contains("->"))
                {
                    int index = input.IndexOf("->");

                    if (lastResult == System.Convert.ToDecimal(input.Substring(0, index)))
                    {
                        mCommand(parser, input.Substring(index + 2), statement, ref lastResult);
                    }
                }
                else
                {
                    if (input.Contains(":") && input.Contains(":=") == false)
                    {
                        int index = input.IndexOf(":");

                        statement.Add(input.Substring(0, index).Replace(" ", ""), input.Substring(index + 1, input.Length - index - 1));

                    }
                    else if (input.StartsWith("pause"))
                    {
                        Console.ReadKey();

                    }
                    else if (input.StartsWith("end"))
                    {
                        Environment.Exit(0);
                    }

                    else
                    {
                        foreach (var item in statement)
                        {
                            if (input.Contains(item.Key))
                            {
                                input = "";
                                mCommand(parser, item.Value, statement, ref lastResult);
                            }
                        }
                        lastResult = parser.ProgrammaticallyParse(input, identifyComments: false);
                        Console.WriteLine(lastResult);
                    }
                }
            }
        }
    }
    catch (Exception e)
    {
        Console.WriteLine("An error occured. Message: " + e.Message);
    }
}

static void mCommand(Mathos.Parser.MathParser parser, string input, Dictionary<string, string> statement, ref decimal lastResult)
{
    input = input.Replace(@"\n", System.Environment.NewLine);

    System.IO.StringReader sr = new System.IO.StringReader(input);

    string _input = sr.ReadLine();

    while (_input != null)
    {
        command(parser, _input, statement, ref lastResult);
        _input = sr.ReadLine();
    }
    sr.Close();
}

Some programmers will certainly argue that the code above is not that optimized and is quite primitive. Well, it serves its purpose and makes Mathos Parser look more like a language.

In the next article I want to implement a while feature into this awesome programming language.

Conclusion: Just because something can parse expressions does not mean it can parse a series of statement. In order to fix this we can either choose to add some features externally, or, go into the parser itself and make it more adjusted to this particular task. This language does not alter Mathos Parser in any way.

Downloads:

Factorial notation in Mathos Parser (1)

In this article series, I would like to look at how Mathos Parser (a very simple expression parser) can be used to perform things that were not originally intended. Today, I am going to show what has to be done to make Mathos Parser able to interpret factorial notation, such as “4!

Already in the parser, we can solve this in at least two different ways:

  • creating a localFunction fact() that will take one parameter and return the factorial of that number
  • using FactorialPower(falling power) instead, that is 4!4 would be 24 and 4!1=4.

Both methods do not require you to change anything in the input string, but they might not be as close to the mathematical notation as we want it to be. Therefore, as a part of this article, I am going to illustrate the changes in the input string that have to be made, to make it understand 4!.

  1. Include Reg Ex name space as following:
    using System.Text.RegularExpressions;
  2. Add these two methods somewhere in the class:
    static decimal factorial(decimal x)
    {
        if(x==1 || x== 0)
        {
            return 1;
        }
        else
        {
            return x * factorial(x - 1);
        }
    }
    
    static string FactorialString(Match m)
    {
        return m.Value + "0";
    }
  3. Define the Mathos Parser and add a definition of the factorial operator including the way it should be executed. Note, at this stage, for this to work, the factorial number has to be in the form of 4!0 or 4!1 ((both result in 24).
    Mathos.Parser.MathParser parser = new Mathos.Parser.MathParser();
    
    parser.OperatorList = new List<string>() {"!" ,"%","^", "/", "*",  "-", "+"}; // removed ":" for division
    parser.OperatorAction.Add("!", (x, y) => factorial(x));
  4. Before the input string can be parsed, perform the following action (assuming you have defined a variable input with a value):
    input = Regex.Replace(input, @"[0-9]+\!", new MatchEvaluator(FactorialString));
  5. Parser the string and store the result:
    decimal result = parser.Parse(input);

This is how we can make Mathos Parser able to understand mathematical notation of factorial. In the next article of this series, we are going to look at how Mathos Parser can be used to construct a new programming language.

A possible change for machine code

In the recent issue, it was reported that machine codes are repeated approximately once per 50 different machines in SKGL 2.0.5.3. The reasons under investigation are:

  • small hash value allows even more collisions.
  • the machine information that is being hashed does not collect all hardware that can be changed.

The first reason is currently in focus, and I have tried to develop a piece of code that now increases the length of the machine code. It would be great if those of you who are able to test this on several machines could do so, and comment(either directly below this thread or here) how frequent the collisions are on different machines! Thank you in advance! 🙂

EDIT 2: This can be done by anyone using Windows:

  1. Download the software below (no installation required): (or download the exe file directly here) NOTE: In Google Chrome, it might tell that the file is dangerous because it is not commonly downloaded. Please right click and press keep.

Machinecode experiment

EDIT: You can also write the machine code you get on your own computer and post it below this thread. (hardware info using dxdiag would be awesome, but the machine code is more important at this point)

public class AnalysisOfMachineCode
{
    [TestMethod]
    public void test()
    {
        Debug.WriteLine(getMachineCode());
    }


    [SecuritySafeCritical]
    public static int getMachineCode()
    {
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("select * from Win32_Processor");
        string collectedInfo = "";
        // here we will put the informa
        foreach (ManagementObject share in searcher.Get())
        {
            // first of all, the processorid
            collectedInfo += share.GetPropertyValue("ProcessorId");
        }

        searcher.Query = new ObjectQuery("select * from Win32_BIOS");
        foreach (ManagementObject share in searcher.Get())
        {
            //then, the serial number of BIOS
            collectedInfo += share.GetPropertyValue("SerialNumber");
        }

        searcher.Query = new ObjectQuery("select * from Win32_BaseBoard");
        foreach (ManagementObject share in searcher.Get())
        {
            //finally, the serial number of motherboard
            collectedInfo += share.GetPropertyValue("SerialNumber");
        }

        // patch luca bernardini
        if (string.IsNullOrEmpty(collectedInfo) | collectedInfo == "00" | collectedInfo.Length <= 3)
        {
            collectedInfo += getHddSerialNumber();
        }

        return getEightByteHash(collectedInfo, 1000000);
    }

    [SecuritySafeCritical]
    public static string getHddSerialNumber()
    {


        // --- Win32 Disk 
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("\\root\\cimv2", "select * from Win32_DiskPartition WHERE BootPartition=True");

        uint diskIndex = 999;
        foreach (ManagementObject partition in searcher.Get())
        {
            diskIndex = Convert.ToUInt32(partition.GetPropertyValue("Index"));
            break; // TODO: might not be correct. Was : Exit For
        }

        // I haven't found the bootable partition. Fail.
        if (diskIndex == 999)
            return string.Empty;



        // --- Win32 Disk Drive
        searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive where Index = " + diskIndex.ToString());

        string deviceName = "";
        foreach (ManagementObject wmi_HD in searcher.Get())
        {
            deviceName = wmi_HD.GetPropertyValue("Name").ToString();
            break; // TODO: might not be correct. Was : Exit For
        }


        // I haven't found the disk drive. Fail
        if (string.IsNullOrEmpty(deviceName.Trim()))
            return string.Empty;

        // -- Some problems in query parsing with backslash. Using like operator
        if (deviceName.StartsWith("\\\\.\\"))
        {
            deviceName = deviceName.Replace("\\\\.\\", "%");
        }


        // --- Physical Media
        searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia WHERE Tag like '" + deviceName + "'");
        string serial = string.Empty;
        foreach (ManagementObject wmi_HD in searcher.Get())
        {
            serial = wmi_HD.GetPropertyValue("SerialNumber").ToString();
            break; // TODO: might not be correct. Was : Exit For
        }

        return serial;

    }

    public static int getEightByteHash(string s, int MUST_BE_LESS_THAN = 1000000000)
    {
        //This function generates a eight byte hash

        //The length of the result might be changed to any length
        //just set the amount of zeroes in MUST_BE_LESS_THAN
        //to any length you want
        uint hash = 0;

        foreach (byte b in System.Text.Encoding.Unicode.GetBytes(s))
        {
            hash += b;
            hash += (hash << 10);
            hash ^= (hash >> 6);
        }

        hash += (hash << 3);
        hash ^= (hash >> 11);
        hash += (hash << 15);

        int result = (int)(hash % MUST_BE_LESS_THAN);
        int check = MUST_BE_LESS_THAN / result;

        if (check > 1)
        {
            result *= check;
        }

        return result;
    }

}
Page 1 of 2:1 2 »