Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    vamsi345
    @vamsi345
    Hello , I'm trying to learn NRules and to start practicing I have write a small rule and trying to get the NotifyChange function called. But When I'm executing the application I'm not getting any error also not any output. could someone please help me where I'm doing wrong
    2 replies
    Sergey V. Kovalenko
    @multiton
    Dear Colleagues, I've just started to work with NRules a couple weeks ago. Like it a lot. But the issue I am getting is performance... I have about 1500 rules, and my rulesRepo.Compile() takes almost 6 seconds. Is anybody had same kind of issue? Please, be so kind, throw me some hints...
    Larry LeBron
    @larrybehlang_gitlab
    @multiton That's not uncommon at all. My solution has been to compile asynchronously and to split my rules up into separate sessions so I can compile them all async in parallel. Obviously by splitting up the rules into separate sessions you lose the clause sharing of the consolidated rete. There are other advantages to splitting them up, though, as it gives you an easy way to update only certain rules. So, that solution may or may not work well for you. It might be possible to speed up compilation by optimizing your rule structure itself, but I'm not sure how much you can expect to gain by that route.
    I haven't done it, but one thought I've had is to split the sessions all up to get compiled and running faster with small parallel sessions. Then, in parallel to all of that, I'd run the longer compilation of all the rules in one session. Once the consolidated rete was ready, I'd switch over to using it. However, that's a lot to jump through for a few seconds :)
    In my experience, the gains from running multiple small sessions in parallel has outweighed the gains of the consolidated session.
    Sergiy Nikolayev
    @snikolayev
    @multiton and @larrybehlang_gitlab one thing to check out is the new extensibility point in nrules to plug in a custom expression compiler, e.g. FastExpressionCompiler (https://github.com/dadhi/FastExpressionCompiler), which could speed up compilation. NRules/NRules#254
    Larry LeBron
    @larrybehlang_gitlab
    Wow, thanks @snikolayev . I wasn't aware of this option!
    Sergey V. Kovalenko
    @multiton
    Thank you Sergiy. Appreciate your help. Does FastExpressionCompiler works on .NET Core, or only .NetFramework?
    2 replies
    William Guterman
    @alentor
    Hello, asking here as I didn't find any info online, is there a way to know which rule being invoked during runtime/debug? The rule coming form Rule# text file
    William Guterman
    @alentor
    Also is there an option to query the loaded rules, from session?
    Sergey V. Kovalenko
    @smithus
    ... here as I didn't find any info online, is there a way to know which rule being invoked during runtime/debug?
    May be like this:
    session.Events.RuleFiredEvent += (object sender, AgendaEventArgs e) => this.myFiredRules.Add(e.Rule); ...correct me if I am wrong.
    Sergiy Nikolayev
    @snikolayev
    @alentor there are many different ways to find out which rule is firing. In the rule’s action you can access the IContext parameter and get the Rule propriety with the rule’s name and other rule metadata. You can also use session debug events as @smithus recommended. You can also use action interceptor (check the wiki)
    @alentor you cannot query which rules are loaded in the session, but you can get then from the RuleRepository
    William Guterman
    @alentor
    @snikolayev @smithus Thank you, exactly what I was needed..
    William Guterman
    @alentor
    @snikolayev What do you mean in the rules action? In my scope I have only access to ISession
    I would like to find out which rules matched my 'when' condition after firing
    William Guterman
    @alentor
    We are using NRules.Langauges to write our rules
    Sergiy Nikolayev
    @snikolayev
    @alentor I was referring to the Then part of a rule, if you wanted to get the name of the rule that’s firing, since that’s how you initially phrased your question. If you are using NRules.Language, you can access context via the static Context variable. If you only have access to the session and want to keep track of which rules are firing, best to use debug events, like noted above.
    Larry LeBron
    @larrybehlang_gitlab

    @snikolayev Is there any way to have an "optional" clause in the NRules DSL that would serve only to fill a value if the clause evaluates to true? I know this would be possible via an Or clause where one of the branches of the Or always evaluates true, but I'd prefer not to have the rule fire twice if the optional branch evaluates true.

    e.g. see this pseudocode:

    Define() {
       bool foundOptionalFact = false;
    
       When()
          // Required clause
          .Exists<FactType>(fact => fact.PassesTest)
         // Optional clause
          .Optional(x => x
              .And(xx => xx
                 .Exists<FactType>(fact => fact.PassesTest)
                 .Let(() => foundOptionalFact , () => true)));
    
       // Then will run as long as long the required clause is evaluated true
       Then(ctx => (foundOptionalFact));
    
    
    }
    Sergiy Nikolayev
    @snikolayev

    Hey @larrybehlang_gitlab - the way you handle optional facts normally is via a Query. Something like this:

                Fact1 requiredFact = default;
                Fact2 optionalFact = default;
    
                When()
                    .Match<Fact1>(() => requiredFact, c => c.Predicate)
                    .Query(() => optionalFact, x => x
                        .Match<Fact2>(o => o.Predicate)
                        .Collect()
                        .Select(c => c.FirstOrDefault()));

    You can also wrap this into an extension method, call it MatchOptional and have a shorthand for it

    The reason this works is because Collect produces a match even if the collection is empty
    Larry LeBron
    @larrybehlang_gitlab
    @snikolayev Thanks! Out of curiosity, is there any way to implement this so it won't continue checking beyond the first matched optional fact since in my case I only care about whether or not such a match exists?
    Sergiy Nikolayev
    @snikolayev
    @larrybehlang_gitlab no, but practically, Collect query is very efficient, so you wouldn’t gain much from using “exists” there if it were possible
    Larry LeBron
    @larrybehlang_gitlab
    @snikolayev I see. But the Collect query you wrote will iterate through every fact of the given type trying to collect all matches, right? Nevertheless, it does seem more efficient that any other alternative I can think of.
    Sergiy Nikolayev
    @snikolayev
    @larrybehlang_gitlab the query won't iterate over the collection unless you write a query that iterates. This one just grabs the first element from the collection. I suppose you can also just select the size of the collection if you don't care about the elements. It is true that the engine will actually collect matched facts in that collection, but it's pretty efficient behind the scenes - it adds an element to a mutable collection and pushes the whole collection down as an update.
    Alberto Gonzalez
    @agonzalezm
    Hi I want to implent a rule string system in my app that can interpret this: (Pattern1 AND Patter2) OR (P3 AND P5) AND NOT P5 ... patterns are regexp or expression define in db and just want the user to configure how they have to match all of them
    can this language be done with nrule or there is another better library to implement this?
    William Guterman
    @alentor
    Hello, are there documentaion for NRules.Language like there is for Fluent Rules DSL https://github.com/NRules/NRules/wiki/Fluent-Rules-DSL
    1 reply
    William Guterman
    @alentor
    Thank you @snikolayev, I was looking for an OR example if it's supported in NRules.Langauge
    1 reply