>我用例子来解释我的问题。
(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