Skip to content

Commit

Permalink
Disjoin patterns without dependencies from prior partial matches. #224
Browse files Browse the repository at this point in the history
When a query/pattern does not depend on preceding matches, it should be separated into an independent sub-network, such that it's only evaluated based on it's inputs chaning, and not based on the preceding partial matches.
The corolary to this is that a binding expression that does not depend on any preceding matches will only evaluate once (hence fixing the BindingEvaluationExceptionTest to introduce the dependency on the preceding fact match).
  • Loading branch information
snikolayev committed Nov 25, 2020
1 parent 22658a1 commit 00194ec
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 17 deletions.
27 changes: 15 additions & 12 deletions src/NRules/NRules/Rete/ReteBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ protected override void VisitPattern(ReteBuilderContext context, PatternElement
}
else
{
if (conditions.Any())
var isJoined = element.Imports.Any();
if (isJoined)
{
var isJoined = element.Imports.Any();
if (isJoined)
if (conditions.Any())
{
BuildSubnet(context, element);

Expand All @@ -137,20 +137,23 @@ protected override void VisitPattern(ReteBuilderContext context, PatternElement
}
else
{
var joinContext = new ReteBuilderContext(context.Rule, _dummyNode);
BuildSubnet(joinContext, element);

joinContext.RegisterDeclaration(element.Declaration);
BuildJoinNode(joinContext, element, conditions);
BuildAdapter(joinContext);
context.AlphaSource = joinContext.AlphaSource;

Visit(context, element.Source);
context.RegisterDeclaration(element.Declaration);
}
}
else
{
Visit(context, element.Source);
var joinContext = new ReteBuilderContext(context.Rule, _dummyNode);
BuildSubnet(joinContext, element);

joinContext.RegisterDeclaration(element.Declaration);
if (conditions.Any())
{
BuildJoinNode(joinContext, element, conditions);
BuildAdapter(joinContext);
}
context.AlphaSource = joinContext.AlphaSource;

context.RegisterDeclaration(element.Declaration);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,8 @@ protected override void SetUpRules()
SetUpRule<TestRule>();
}

private static readonly Func<string> SuccessfulBinding = () => "value";
private static readonly Func<string> ThrowBinding = () => throw new InvalidOperationException("Binding failed");
private static readonly Func<FactType, string> SuccessfulBinding = f => "value";
private static readonly Func<FactType, string> ThrowBinding = f => throw new InvalidOperationException("Binding failed");

public class FactType
{
Expand All @@ -156,16 +156,16 @@ public class FactType

public class TestRule : Rule
{
public Func<string> Binding = SuccessfulBinding;
public Func<FactType, string> Binding = SuccessfulBinding;

public override void Define()
{
FactType fact = null;
string binding = null;

When()
.Match<FactType>(() => fact, f => f.TestProperty.StartsWith("Valid"))
.Let(() => binding, () => Binding());
.Match(() => fact, f => f.TestProperty.StartsWith("Valid"))
.Let(() => binding, () => Binding(fact));
Then()
.Do(ctx => NoOp());
}
Expand Down

0 comments on commit 00194ec

Please sign in to comment.