我对使用NRule实现推理有疑问。
我有以下有关使用NRule实现推理的查询,如果您能提供您的输入,那将是很好的。
首先让我解释一下我正在尝试的情况。这是非常基本的规则,其中我创建了2条规则。第一条规则是,当客户是首选客户时,则给予10%的折扣。第二条规则是,每当应用折扣时,便通知客户。在这里,我附加了示例程序InferenceTest.cs的代码供您参考。
现在,随着这两个规则的执行,我正在观察的行为进入了无限循环。原因是每次在第一个规则中更新客户对象后,它都会无限期地递归运行这两个规则。如果我以在下一次执行期间将其评估为false的方式明确地制定了第一条规则的条件,那么它将很好地工作。
现在的问题是– 1 /规则作者是否必须以编写规则条件的方式来照顾它,使其在推理执行期间不会重新触发规则?这是一个硬性限制吗?可能在具有大量规则的系统中,规则创建者可能无法考虑所有不同的规则,然后以不会陷入无限循环的方式编写新规则。 2 /是否将每个规则的重复性标记设置为false,在这种情况下是最佳的推荐方案?
public class InferenceTest {
static void Main(string[] args) {
//Load rules
var repository = new NRules.Fluent.RuleRepository();
repository.Load(x => x.From(typeof(PreferredCustomerDiscountRule).Assembly));
//Compile rules
var factory = repository.Compile();
//Create a working session
var session = factory.CreateSession();
//Load domain model
var customer = new Customer("John Doe") { IsPreferred = true };
//Insert facts into rules engine's memory
session.Insert(customer);
//Start match/resolve/act cycle
session.Fire();
Console.ReadLine();
}
}
public class PreferredCustomerDiscountRule : Rule {
public override void Define() {
Customer customer = null;
When()
.Match<Customer>(() => customer, c => c.IsPreferred);
Then()
.Do(ctx => ApplyDiscount(customer, 10.0))
.Do(ctx => ctx.Update(customer));
}
private static void ApplyDiscount(Customer customer, double discount) {
customer.DiscountPercent = discount;
Console.WriteLine("Discount applied----", customer.Name);
}
}
public class DiscountNotificationRule : Rule {
public override void Define() {
Customer customer = null;
When()
.Match<Customer>(() => customer, c => c.DiscountPercent.HasValue);
Then()
.Do(_ => NotifyAboutDiscount(customer));
}
private static void NotifyAboutDiscount(Customer customer) {
Console.WriteLine("---Customer {0} has instant discount of {1}%", customer.Name, customer.DiscountPercent);
}
}
public class Customer {
public string Name { get; private set; }
public bool IsPreferred { get; set; }
public Nullable<double> DiscountPercent { get; internal set; }
public Customer(string name) {
Name = name;
}
}