问题描述
我具有用于车站和火车的以下事实模板:
(deftemplate station
(slot name (type SYMBOL))
(slot status (type SYMBOL) (default open)))
(deftemplate train
(slot departs-from (type SYMBOL))
(multislot stops-at (type SYMBOL)))
departs-from
和stops-at
槽都引用了name
个电台。
(deffacts trains-and-stations
(station (name station-a))
(station (name station-b))
(station (name station-c))
(train (departs-from station-a) (stops-at unkNown-station))
(train (departs-from station-a) (stops-at station-b station-c))
(train (departs-from station-b) (stops-at station-c station-a)))
我想制定一条规则来测试每列火车中是否存在车站事实:
(defrule check-valid-stations
?train <- (train (departs-from ?from) (stops-at $?stops))
(not (exists (station (name ?from))))
=>
(printout t "Route of " $train " contains an unkNown station!" crlf))
以上规则仅检查出发站是否有效,如何检查出发站和每个停靠站是否都存在?
解决方法
最简单的方法是有单独的规则,这些规则检查发车和停站的站,并在每次发现未知站时触发。如果您希望打印一条消息而与未知车站的数量无关,那么请为每个列车事实添加一个ID槽,以便您可以编写更复杂的模式,该模式将与每个列车仅匹配一次。
CLIPS (6.31 6/12/19)
CLIPS>
(deftemplate station
(slot name (type SYMBOL))
(slot status (type SYMBOL) (default open)))
CLIPS>
(deftemplate train
(slot id)
(slot departs-from (type SYMBOL))
(multislot stops-at (type SYMBOL)))
CLIPS>
(deffacts trains-and-stations
(station (name station-a))
(station (name station-b))
(station (name station-c))
(train (id 1) (departs-from station-a) (stops-at unknown-station))
(train (id 2) (departs-from station-a) (stops-at station-b station-c))
(train (id 3) (departs-from station-b) (stops-at station-c station-a))
(train (id 4) (departs-from some-station) (stops-at station-c station-a bad-location)))
CLIPS>
(defrule check-valid-stations-departs
?train <- (train (departs-from ?from))
(not (station (name ?from)))
=>
(printout t "Route of " ?train " contains an unknown station: " ?from crlf))
CLIPS>
(defrule check-valid-stations-stops
?train <- (train (stops-at $? ?to $?))
(not (station (name ?to)))
=>
(printout t "Route of " ?train " contains an unknown station: " ?to crlf))
CLIPS>
(defrule check-valid-stations
?train <- (train (id ?id) (departs-from ?from))
(exists (or (not (station (name ?from)))
(and (train (id ?id) (stops-at $? ?to $?))
(not (station (name ?to))))))
=>
(printout t "Route of " ?train " contains an unknown station!" crlf))
CLIPS> (reset)
CLIPS> (run)
Route of <Fact-7> contains an unknown station: some-station
Route of <Fact-7> contains an unknown station!
Route of <Fact-7> contains an unknown station: bad-location
Route of <Fact-4> contains an unknown station!
Route of <Fact-4> contains an unknown station: unknown-station
CLIPS>