首页 > 解决方案 > 如何在不提供属性值的情况下在 Clara 中插入整个事实

问题描述

以下 Clara 规则代码通过为事实类型的所有属性提供值来插入事实:

(defrule vips-200-promotion
  "This rule creates a special promotion for VIPs that spend +$200"
  [Customer (= true vip) (= ?customerId customerId)]
  [Order (> total 200) (= ?customerId customerId)]
  =>
  (insert! (Promotion. "PROMO-XMAS" ?customerId)));;; Inserts a Promotion fact with promoId = PROMO-XMAS and customerId = value in ?customerId

(defquery get-promos
  []
  [?promotion <- Promotion]).  

但是,如何在不为其属性提供值的情况下插入先前已绑定的事实(因为您在绑定变量中拥有具有值的整个事实)?

像这儿:

(defrule vips-promotion
  "This rule creates a special promotion for VIPs"
  [?customer <- Customer (= true vip) (= ?customerId customerId)]

  =>
  (insert! (Customer. ?customer))    ;;; This line fails since insert! is expecting values for all the fact's attribute, but I want to just pass ?customer, which contains the value of the matched Customer.

(defquery get-customers
  []
  [?customerx <- customer])

标签: clojureclara-rule-engine

解决方案


稍作修改,添加<-到绑定:

(defrule vips-promotion
  "This rule creates a special promotion for VIPs"
  [?customer <- Customer (= true vip) (= ?customerId customerId)]

  =>
  (insert! (Customer. ?customer))

这里的简单答案似乎是您必须向 Customer 类添加一个 Copy 构造函数。

附带说明一下,像上面提到的规则将永远循环,因为 rhs(Right Hand Side) 插入然后会触发 lhs(Left Hand Side),然后由于前向链接规则的性质,它会触发 rhs 并永远重复引擎。


推荐阅读