About

This is my blog about programming topics in the Microsoft .net environment (.net, c#, sql server etc.) and about functional programming (f#, haskell). I will also write about building parsers and domain specific languages and compilers. Another topic i realy like are machine learning algorithms (neuronal networks, deep learning, support vector machines).


22 Comments on “About”

  1. I just wanted to let you know how much I have enjoyed your writing and the way you explain and implement stuff…great stuff….great work!

    • netmatze says:

      Hello Jorge,

      Many thanks to your comment I am very pleased, that you like what and how I write. I will do my best to continue to write about some interesting topics.

      Thanks
      Netmatze

  2. MIke P says:

    Hi,

    Well done on this piece of work – It’s great and I learnt a lot from it.

    I would like to ask how you would approach to adding a “Then” statement? i.e.
    string ruleText = ” (Children = 2 && Married = false) || Age >= 40 Then “SetTaxBand”;
    Evaluator evaluator = new Evaluator();
    evaluator.Execute(ruleText, person);

    In this case, SetTaxBand is a method on the Person object which will maybe set a property or execute some code.

    Your thoughts are much appreciated

    • netmatze says:

      Hi Mike,

      I see what you want to accomplish. I implemented it in the ruleengine project, it is a little bit complicated because the parser i wrote is written to validate expressions, and what you need is a set operation but i could change the parser and the expression evaluator to set a property of the Person object. So here is the test i wrote to check if the set operation works. (it works only for one set operation you can not write (set property1 = 1 set property2 = 2)
      [TestMethod]
      public void SimpleExpressionEvaluatorWithSet()
      {
      Person person1 = new Person()
      {
      Name = “Mathias”,
      Age = 36,
      Children = 2,
      Married = true,
      Birthdate = new DateTime(1976, 5, 9)
      };
      Evaluator evaluator = new Evaluator();
      var result = evaluator.Evaluate( ” (Age > 10) set Married = false “, person1);
      Assert.AreEqual(result, true);
      Assert.AreEqual(person1.Married, false);
      }
      I hope that is what you need.

      Greetings
      netmatze

      • Mike says:

        Hi netmatze,

        Wow, thanks for the quick response.It’s almost what I was after but in my scenario I need to call a method on the class (an action if you like). ideally, it would be like

        If logic Then Action Else OtherAction

        Could this be possible?

        Also, if you are using the expression evaluator, is there any way to precompile the expression so that if you are evaluating many objects, you do not need to read the expression in every time?

        Many thanks in advance for your time and help

        Mike

      • netmatze says:

        Hello Mike,

        I implemented the then and else pattern in the expression evaluator and i checked it in. Here you can see the test that checks if then and else work correct.
        [TestMethod]
        public void SimpleExpressionEvaluatorWithThenElseMethod()
        {
        Person person1 = new Person()
        {
        Name = “Mathias”,
        Age = 36,
        Children = 2,
        Married = true,
        Birthdate = new DateTime(1976, 5, 9)
        };
        Person person2 = new Person()
        {
        Name = “Anna”,
        Age = 32,
        Children = 2,
        Married = false,
        Birthdate = new DateTime(2002, 2, 2)
        };
        Evaluator evaluator = new Evaluator();
        var result1 = evaluator.Evaluate(
        ” (Age < 10) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) ", person1);
        Assert.AreEqual(result1, false);
        Assert.AreEqual(person1.CancelBenefits, true);
        Assert.AreEqual(person1.ReceiveBenefits, false);
        var result2 = evaluator.Evaluate(
        ” (Age > 10) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) “, person2);
        Assert.AreEqual(result2, true);
        Assert.AreEqual(person2.CancelBenefits, false);
        Assert.AreEqual(person2.ReceiveBenefits, true);
        }
        If you want to precompile the expression then it is possible to evaluate the expression only once and the we can reuse the list of the Expressions and the symbol table. I added the following methodes to the evaluator.
        public Tuple<List, Dictionary>
        PreEvaluate(string evaluationText)
        {
        ExpressionEvaluatorLexer expressionEvaluatorLexer = new ExpressionEvaluatorLexer(evaluationText, 1);
        ExpressionEvaluatorParser expressionEvaluatorParser = new ExpressionEvaluatorParser(expressionEvaluatorLexer);
        var AbstractSyntaxTreeNodeList = expressionEvaluatorParser.BuildParseTree();
        ExpressionEvaluatorExecutor expressionEvaluator = new ExpressionEvaluatorExecutor();
        var symbolTable = expressionEvaluatorParser.SymbolTable;
        return new Tuple<List, Dictionary>(
        AbstractSyntaxTreeNodeList, symbolTable
        );
        }

        public bool ExecuteEvaluate(Tuple<List,
        Dictionary> values, T objectValue)
        {
        ExpressionEvaluatorExecutor expressionEvaluator = new ExpressionEvaluatorExecutor();
        var result = expressionEvaluator.Evaluate(values.Item1, values.Item2, objectValue);
        return result;
        }

        Then i added a new method to the RuleValidator to show how you could use it for multible Persons.
        public bool ValidateExpressionRulesAll(T[] values, string evaluatorExpression)
        {
        Evaluator evaluator = new Evaluator();
        var tuple = evaluator.PreEvaluate(evaluatorExpression);
        foreach (var value in values)
        {
        if (!evaluator.ExecuteEvaluate(tuple, value))
        return false;
        }
        return true;
        }
        Here is the test that shows how to use a then – else expression that is preinterpreted.
        [TestMethod]
        public void SimpleExpressionPreEvaluatorWithThenElseMethod()
        {
        Person person1 = new Person()
        {
        Name = “Mathias”,
        Age = 36,
        Children = 2,
        Married = true,
        Birthdate = new DateTime(1976, 5, 9),
        CancelBenefits = false,
        ReceiveBenefits = false
        };
        Person person2 = new Person()
        {
        Name = “Anna”,
        Age = 32,
        Children = 2,
        Married = false,
        Birthdate = new DateTime(2002, 2, 2),
        CancelBenefits = false,
        ReceiveBenefits = false
        };
        Evaluator evaluator = new Evaluator();
        var tuple = evaluator.PreEvaluate(
        ” (Age 10) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) “);
        Assert.AreEqual(result, true);
        Assert.AreEqual(person1.ReceiveBenefits, true);
        Assert.AreEqual(person2.ReceiveBenefits, true);
        }

        I hope that is what you need.

        Greetings
        netmatze

  3. Mike says:

    Hi netmatze,

    I am seriously impressed! Exactly what I need. A couple more questions if you don’t mind.

    1) In your SimpleExpressionEvaluator, what is the purpose of the file ExpressionEvaluator.txt?
    2) Have you come across or found a way to allow a business user to construct rules in web page or tool? I have seen a few rule packages that do this but wondered if it is something you have found in your travels.

    Sincere thanks again for implementing this

    Mike

    • netmatze says:

      Hello Mike,

      To anwser your questions, the SimpleExpressionEvaluator.txt file contains the ebnf (Extended Backus–Naur form) of the expression evaluator. When i started the project i wrote a definition in ebnf. With that definition i checked if the expressions i wanted are defined correct (with the antlr plugin for eclipse). I checked it in to have the definition at the same place as the lexer and the parser. To your second question i am sorry but i never had the task setting to consturct rules in a web page for business users (sounds like you need a javascript rule engine) so i think i can not help you at that point.

      Greetings
      netmatze

  4. Hi Netmaze,
    I noticed several unit tests failed, though i hink I have the latest code e.g. the one below fails as person1.CancelBenefits is ‘false’ . is this expected to fail or have I the wrong code versions somehow?
    Thank You

    [TestMethod]
    public void SimpleExpressionEvaluatorWithThenElseMethod()
    {
    Person person1 = new Person()
    {
    Name = “Mathias”,
    Age = 36,
    Children = 2,
    Married = true,
    Birthdate = new DateTime(1976, 5, 9)
    };
    Person person2 = new Person()
    {
    Name = “Anna”,
    Age = 32,
    Children = 2,
    Married = false,
    Birthdate = new DateTime(2002, 2, 2)
    };
    Evaluator evaluator = new Evaluator();
    var result1 = evaluator.Evaluate(
    ” (Age < 10) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) ", person1);
    Assert.AreEqual(result1, false);
    Assert.AreEqual(person1.CancelBenefits, true);
    Assert.AreEqual(person1.ReceiveBenefits, false);
    var result2 = evaluator.Evaluate(
    ” (Age > 10) then SetCanReceiveBenefits(true) else SetCancelBenefits(true) “, person2);
    Assert.AreEqual(result2, true);
    Assert.AreEqual(person2.CancelBenefits, false);
    Assert.AreEqual(person2.ReceiveBenefits, true);
    }

  5. Hi,
    Sorry….found just 3 failing tests – all others work fine. The ones not working are :

    SimpleExpressionStringIsNullMethod() – fails on var result1 = evaluator.Evaluate(
    ” Name = ‘Mathias’ “, person1); – Result is false – expects true.

    SimpleExpressionPreEvaluatorEventPersonWithThenMethod() – In ExpressionEvaluator null property exception at var property = objectValue.GetType().GetProperty(propertyName.Item2);

    SimpleRuleLoaderPersonValidateRulesCount() – null ‘expression’ parameter in CompileRule(…) of the RuleEngine.cs file.

    Not sure if these arose from prior fix or were always present.
    Thanks
    Phil

  6. Damien Steiger says:

    Hello,

    Thanks for the great utility. I have been using the rule engine with much success, However I am unable to do a couple of things that I was hoping for. Specifically, I’d like to be able to do partial string matching/wildcarding. For instance, I’d like to be able to do something like “LastName like ‘Mac*'” or “ProductName like ‘*hat*'”

    Please advise.

    Thanks!
    Damien

  7. mohammad says:

    hello sir
    i am using your amazing rule engine thank you for sharing you useful experience . the engine works with out any problems on .net regular datatypes but i tried to establish a condition on a class which is used in another class and the engine always throw exception
    here is my classes
    public class Gender{
    public int id {get;set;}
    public string Name{get;set;}
    }
    public class person{
    public Gender gender{get;set;}
    public string Name{get;set;}
    }
    and they are rules
    object s = (object)new Gender { Id = 1, Name = “Female” };
    var rule = new Rule(“Gender”, Operator.Equal, s);

    var ressult = ruleFunc(person1);

    // it always return false

    Console.WriteLine(ressult);
    I even tried to implement condition as expression and it always throw Exception
    var circumstance=”gender.id= 1″
    moreovere I also had a look at this test (SimpleRuleLoaderPersonAddressValidateRulesAll) but i wonder to know is there any other way just like as I am trying
    i am appreciated and thank you for your time

    • netmatze says:

      Hello mohammad,

      The problem with using a Gender Object in the Person class is that for that the rule engine had to check the properties of the inner object but that is not implemented in the rule engine, it works only with basic types (string, int, double, DateTime …). It would be a nice feature and if i find the time i will implement it and write a blog post.

      Greetings
      netmatze

  8. Saro says:

    Hello… Im reviewing this engine. How do we check isrequired???

    • netmatze says:

      Hello Saro,

      I do not exactly understand your question. What do you want to check? Maybe you can give me a code example what you want to accomplish.

  9. Nick says:

    Hi Netmatze,
    thanks for your great work on rules!

    I’m trying to use your engine to handle discounts in an order management process for an ecommerce. My need is to set discounts on some products based on other info related to customer or other property.

    As an example, suppose I want to give a 15% discount on all DVD to married persons. I have created the following (simplfied) classes:

    public class Product
    {
    public string ProdID { get; set; }
    public string pType { get; set; }
    public string productName { get; set; }
    public double price { get; set; }
    public double discount;
    }

    public class Cart
    {
    private List products = new List();
    public Person customer { get; set; }

    public void Add(Product prod) {
    products.Add(prod);
    }

    public List Products {
    get { return products; }
    }
    }

    And then I create a possible order with this code:

    Cart cart= new Cart();
    cart.Add(new Product( { ProdID = “D123”, productName = “Star Wars”, pType = “DVD”, price = 14.99, discount = 0 });
    cart.Add(new Product( { ProdID = “D567”, productName = “Ghostbuster”, pType = “DVD”, price = 19.99, discount = 0 });
    cart.Add(new Product( { ProdID = “BABC”, productName = “Ghostbuster”, pType = “BOOK”, price = 7.99, discount = 0 });
    cart.customer= new Person() { Name = “mathias”, Married = true };

    Now I want to set discount=15 to all the products of pType “DVD”, only if the Person is married.

    I tried to create some rules, but I was not able to combine different rules on different objects.

    Is it possible to do this with your tool ?

    Many thanks,
    Nick.

    • netmatze says:

      Hello Nick,

      It took some time but i tried your example and it works here is the code (i had to make some additions to your Cart class!):

      public class Cart
      {
      private System.Collections.Generic.List products =
      new System.Collections.Generic.List();
      public Person customer { get; set; }

      public void Add(Product prod)
      {
      products.Add(prod);
      }

      private int discont;

      public int Discont
      {
      get { return discont; }
      set
      {
      discont = value;
      SetDiscont(discont);
      }
      }

      private void SetDiscont(int discont)
      {
      foreach(var product in products)
      {
      product.price -= product.price / 100 * 15;
      }
      }

      public bool Married
      {
      get { return customer.Married; }
      }

      public System.Collections.Generic.List Products
      {
      get { return products; }
      }
      }

      That is the Test that adds a discount to the products if the Customer in the Cart is Married.
      [TestMethod]
      public void SimpleRuleLoaderProductEvaluateExpression()
      {
      Cart cart = new Cart();
      cart.Add(new Product()
      { ProdID = “D123”, productName = “Star Wars”, pType = “DVD”, price = 14.99, discount = 0 });
      cart.Add(new Product()
      { ProdID = “D567”, productName = “Ghostbuster”, pType = “DVD”, price = 19.99, discount = 0 });
      cart.Add(new Product()
      { ProdID = “BABC”, productName = “Ghostbuster”, pType = “BOOK”, price = 7.99, discount = 0 });
      cart.customer = new Person() { Name = “mathias”, Married = true };

      var rule = new Rule(” (Married = true) set Discont = 15 “);

      Debug.WriteLine(“Product before Rule Expression execution!”);
      foreach (var product in cart.Products)
      {
      Debug.WriteLine(“Product: ” + product.productName + ” Price: ” + product.price);
      }

      RuleValidator ruleValidator = new RuleValidator();
      var result = ruleValidator.ValidateExpressionRules(cart,
      rule);
      Debug.WriteLine(“Product after Rule Expression execution!”);
      foreach (var product in cart.Products)
      {
      Debug.WriteLine(“Product: ” + product.productName + ” Price: ” + product.price);
      }
      Assert.AreEqual(result, true);
      }

      I hope that solves your problem!

      Greetings
      netmatze


If you have a note or a question please write a comment.

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s