有没有办法对 Jess 进行参数,它永远不会在同一规则中使用具有不同名称的变量?



>我用例子来解释我的问题。

(deftemplate point (slot a)(slot b))

(assert (point (a 1)(b 1)))    
(assert (point (a 1)(b 2)))    
(assert (point (a 2)(b 2)))

我想通过避免具有相同 a 和 b 值的点来获得所有可能的积分。(否 [a,b] = [1,1] v [2,2] v ..)

(defrule r1    
(point (a ?x)(b ?y))    
(test (neq ?x ?y))    
=>    
(printout t "Point (a = " ?x ")(b = " ?y ")" crlf))

Point (a = 1)(b = 2) 

好!

优化性能:我想避免通过"测试"条件元素。(测试 (neq ?x ?y))

那么有没有办法对引擎进行参数化,它永远不会在同一规则中使用具有不同名称的变量?

目的是使用..

(defrule r1
(point (a ?x)(b ?y))
=>
(printout t "Point (a = " ?x ")(b = " ?y ")" crlf))

编写此规则的最有效方法是这样的:

(defrule r1    
(point (a ?x)(b ?y&~?x))    
=>    
(printout t "Point (a = " ?x ")(b = " ?y ")" crlf))

如果标准函数集不够,您可以随时使用 Jess API。因此,可以编写一个反射样式的函数来计算事实的复杂属性。

; define an additional template for storing the property for a point
(deftemplate point (slot a)(slot b)(slot c)(slot d))
(deftemplate attr (slot point)(slot isdiff))
; define a function computing whether all slots are different
(deffunction alldiff (?factid)
(bind ?res TRUE)
(bind ?lov (create$))
(foreach ?slot (((engine) findDeftemplate "point") getSlotNames)
(bind ?v (fact-slot-value ?factid ?slot))
(if (member$ ?v ?lov) then (bind ?res FALSE) (break)
else (bind ?lov (create$ ?lov ?v)))
)
(return ?res)
)
; one rule to create the attr fact for a point
(defrule createattr
?point <- (point)
(not (attr (point ?point)))
=>
(bind ?isdiff (alldiff ?point))
(assert (attr (point ?point)(isdiff ?isdiff)))
)
; rule using the attr fact where slot isdiff is TRUE
(defrule useattr
?point <- (point (a ?a)(b ?b)(c ?c)(d ?d))
(attr (point ?point)(isdiff TRUE))
=>
(printout t "a=" ?a ", b=" ?b ", c=" ?c ", d=" ?d crlf)
)
; test
(deffacts insp
(point (a 1)(b 2)(c 3)(d 4))
(point (a 1)(b 1)(c 3)(d 4))
(point (a 1)(b 2)(c 2)(d 4))
(point (a 1)(b 2)(c 3)(d 3))
)
(reset)
(run)

输出:

Jess> (batch different.clp)
a=1, b=2, c=3, d=4
5

相关内容

  • 没有找到相关文章

最新更新