读取对象的槽值的语法是什么,其中该对象是一个变量,并且在 defrule 内部?

What is the syntax for reading a slot value of an object, where that object is a variable, and inside a defrule?

我一直在翻阅文档,但找不到解决方案,如果我在某处遗漏了这一点,请原谅我。这是我的问题:我有两个 PART class 实例,part1 和 part2,PART class 有一个名为 hasPort 的插槽。如果端口已连接,我想要一个匹配两个部分实例的规则。每个端口都是 PORT class 的一个实例,它有一个名为 'connectedTo' 的插槽,用于存储连接的 PORT 实例。

首先,我的 class 个对象:

(defclass PART  (is-a USER)
   (role concrete)
   (slot affectsProperty (type INSTANCE))
   (slot directlyConnected (type INSTANCE))
   (slot hasPort (type INSTANCE))
   (slot hasSensor (type INSTANCE))
   (slot hasIssue (type INSTANCE))
   (multislot secondary-types))

(defclass PORT  (is-a USER)
   (role concrete)
   (slot connectedTo (type INSTANCE))
   (multislot secondary-types))

我试过如下规则:

(defrule rule0
   ?part1 <- (object (is-a PART) (hasPort ?port1))
   ?part2 <- (object (is-a PART) (hasPort ?port2))
   ?port1 <- (object (is-a PORT) (connectedTo ?port2))
   =>  
   ;(assert (directlyConnected ?part1 ?part2))
   (printout t "Found connected parts "
     (instance-name ?part1) " "
     (instance-name ?part2) " by ports "
     (instance-name ?port1) " "
     (instance-name ?port2)
     crlf))

我也试过类似下面的方法:

(defrule rule0
   ?part1 <- (object (is-a PART) (hasPort ?port1))
   ?part2 <- (object (is-a PART) (hasPort ?port2))
   ?port2 <- (send ?port1 get-connectedTo)
   =>  
   ;(assert (directlyConnected ?part1 ?part2))
   (printout t "Found connected parts "
     (instance-name ?part1) " "
     (instance-name ?part2) " by ports "
     (instance-name ?port1) " "
     (instance-name ?port2)
     crlf))

甚至像下面这样的东西:

(defrule rule0
   ?part1 <- (object (is-a PART) (hasPort ?port1))
   ?part2 <- (object (is-a PART) (hasPort ?port2))
   ?port3 <- (send ?port1 get-connectedTo)
   (test (eq ?port3 ?port2))
   =>  
   ;(assert (directlyConnected ?part1 ?part2))
   (printout t "Found connected parts "
     (instance-name ?part1) " "
     (instance-name ?part2) " by ports "
     (instance-name ?port1) " "
     (instance-name ?port2)
     crlf))

除了可能的方法之外,如果您能分享哪种方法是最 "clips" 编写此规则的自然方式,那将不胜感激。

如果您首先放置第三个模式,那么您的第一条规则将起作用,这样变量 ?port1 在被 hasPort 引用之前绑定到实例地址 插槽。

         CLIPS (6.31 6/12/19)
CLIPS> 
(defclass PART  (is-a USER)
   (role concrete)
   (slot affectsProperty (type INSTANCE))
   (slot directlyConnected (type INSTANCE))
   (slot hasPort (type INSTANCE))
   (slot hasSensor (type INSTANCE))
   (slot hasIssue (type INSTANCE))
   (multislot secondary-types))
CLIPS> 
(defclass PORT  (is-a USER)
   (role concrete)
   (slot connectedTo (type INSTANCE))
   (multislot secondary-types))
CLIPS>    
(defrule rule0
   ?port1 <- (object (is-a PORT) (connectedTo ?port2))
   ?part1 <- (object (is-a PART) (hasPort ?port1))
   ?part2 <- (object (is-a PART) (hasPort ?port2))
   =>  
   (printout t "Found connected parts "
     (instance-name ?part1) " "
     (instance-name ?part2) " by ports "
     (instance-name ?port1) " "
     (instance-name ?port2)
     crlf))
CLIPS> (make-instance port2 of PORT)
[port2]
CLIPS> (make-instance port1 of PORT (connectedTo (instance-address [port2])))
[port1]
CLIPS> (make-instance part1 of PART (hasPort (instance-address [port1])))
[part1]
CLIPS> (make-instance part2 of PART (hasPort (instance-address [port2])))
[part2]
CLIPS> (run)
Found connected parts [part1] [part2] by ports [port1] [port2]
CLIPS>

您可以 link 将实例名称与每个实例的预定义 名称 槽一起使用,而不是使用实例地址作为槽值。

CLIPS> (clear)
CLIPS> 
(defclass PART  (is-a USER)
   (role concrete)
   (slot affectsProperty (type INSTANCE-NAME))
   (slot directlyConnected (type INSTANCE-NAME))
   (slot hasPort (type INSTANCE-NAME))
   (slot hasSensor (type INSTANCE-NAME))
   (slot hasIssue (type INSTANCE-NAME))
   (multislot secondary-types))
CLIPS> 
(defclass PORT  (is-a USER)
   (role concrete)
   (slot connectedTo (type INSTANCE-NAME))
   (multislot secondary-types))
CLIPS>    
(defrule rule0
   (object (is-a PART) (name ?part1) (hasPort ?port1))
   (object (is-a PART) (name ?part2) (hasPort ?port2))
   (object (is-a PORT) (name ?port1) (connectedTo ?port2))
   =>  
   (printout t "Found connected parts " ?part1 " " ?part2 
               " by ports " ?port1 " " ?port2 crlf))
CLIPS> (make-instance port1 of PORT (connectedTo [port2]))
[port1]
CLIPS> (make-instance port2 of PORT)
[port2]
CLIPS> (make-instance part1 of PART (hasPort [port1]))
[part1]
CLIPS> (make-instance part2 of PART (hasPort [port2]))
[part2]
CLIPS> (run)
Found connected parts [part1] [part2] by ports [port1] [port2]
CLIPS>