CLIPS中嵌套多槽字段建模现实工件的技术问题咨询
现实工件建模中CLIPS嵌套数据映射的问题解决
背景
我正在对现实工件建模,使用CLIPS 6.4处理包含嵌套流程信息的系统推理,但在将深度嵌套的C++数据结构映射到CLIPS数据类型时遇到了困难。
C++数据结构示例
struct Vehicle { enum Category category; std::list<Engine> engines; std::list<Wheel> wheels; std::list<Instrument> instruments; }; struct ORing { enum metal_type; bool has_seal; float diameter; float length; float weight; }; struct Piston { int foo; float foobar; std::string foofoo; std::list<ORing> orings; }; struct Engine { std::list<Piston> piston; float weight; }; struct Wheel { float diameter; bool has_alloy; }; struct Widget { std::string name; }; struct Instrument { std::string name; bool is_electronic; std::list<Widget> widgets; };
对应的CLIPS数据类型定义
(deftemplate vehicle (slot category (type SYMBOL) (allowed-symbols CAR BUS TRUCK TRAIN SHIP AIRCRAFT)) (multislot engines (type SYMBOL)) (multislot wheels (type SYMBOL)) (multislot instruments (type SYMBOL)) ) (deftemplate engine (multislot pistons (type SYMBOL)) (slot weight (type FLOAT) (range 0.01 ?VARIABLE) ) ) (deftemplate wheel (slot diameter (type FLOAT) (range 0.01 ?VARIABLE) ) (slot has_alloy (type SYMBOL) (allowed-symbols YES NO) ) ) (deftemplate widget (slot name (type STRING)) ) (deftemplate instrument (slot name (type STRING)) (slot is_electronic (type SYMBOL) (allowed-symbols YES NO) ) (multislot widget (type SYMBOL)) )
问题解答
1. 如何断言一个所有槽位均填充完成的vehicle事实?
需要先断言嵌套的子事实(如engine、wheel、instrument等),再将这些子事实的引用(通常是事实索引或自定义标识符)填入vehicle的多槽中。示例如下:
; 先断言子事实 (assert (widget (name "fuel-sensor-widget"))) (assert (instrument (name "fuel-gauge") (is_electronic YES) (widget 1))) ; 1是widget事实的索引 (assert (wheel (diameter 18.5) (has_alloy YES))) (assert (engine (weight 250.0) (pistons 2))) ; 假设2是已断言的piston事实索引 ; 最后断言vehicle事实,引用子事实的索引 (assert (vehicle (category CAR) (engines 3) (wheels 2) (instruments 1)))
注:CLIPS中事实被断言后会自动获得唯一索引,也可以用gen-id生成自定义标识符来关联子事实。
2. 如何获取多槽字段并检查其中条目数量?
可以用$?匹配多槽,结合length$函数获取条目数量。示例:
(defrule count-vehicle-engines (vehicle (category ?cat) (engines $?engine-list)) => (printout t "Vehicle of category " ?cat " has " (length$ ?engine-list) " engines." crlf) )
length$ ?engine-list会返回多槽中元素的个数。
3. 如何从多槽字段中获取第i个元素?
CLIPS中多槽的元素索引从1开始,用nth$函数获取指定位置的元素。示例:
(defrule get-second-engine (vehicle (engines $?engine-list)) => (if (> (length$ ?engine-list) 1) then (bind ?second-engine (nth$ 2 ?engine-list)) (printout t "Second engine's fact index: " ?second-engine crlf) ) )
nth$ 2 ?engine-list会返回多槽中第2个元素。
4. 如何从多槽字段的第i个元素中获取指定字段?
需要先通过索引获取子事实的引用,再用fact-slot-value函数提取子事实的槽值。以获取第2个引擎中第2个ORing的metal_type为例:
; 首先补充缺失的piston和oring模板 (deftemplate piston (slot foo (type INTEGER)) (slot foobar (type FLOAT)) (slot foofoo (type STRING)) (multislot orings (type SYMBOL)) ) (deftemplate oring (slot metal_type (type SYMBOL)) (slot has_seal (type SYMBOL) (allowed-symbols YES NO)) (slot diameter (type FLOAT)) (slot length (type FLOAT)) (slot weight (type FLOAT)) ) (defrule get-oring-metal-type (vehicle (engines $?engine-list)) => ; 先获取第2个引擎的ID (bind ?second-engine-id (nth$ 2 ?engine-list)) ; 获取该引擎的第2个piston ID (bind ?second-piston-id (nth$ 2 (fact-slot-value ?second-engine-id pistons))) ; 获取该piston的第2个oring ID (bind ?second-oring-id (nth$ 2 (fact-slot-value ?second-piston-id orings))) ; 提取该oring的metal_type (bind ?metal-type (fact-slot-value ?second-oring-id metal_type)) (printout t "Second engine's second ORing metal type: " ?metal-type crlf) )
5. 如何向多槽字段添加/移除条目?
使用modify命令结合多槽操作符来更新已断言的事实:
添加条目
(defrule add-third-engine (vehicle (fact-index ?vid) (engines $?engine-list)) (engine (fact-index ?eid)) ; 要添加的新引擎事实 => ; 在engines多槽末尾添加新引擎ID (modify ?vid (engines ?engine-list ?eid)) )
移除条目
通过模式匹配定位并移除:
(defrule remove-third-engine (vehicle (fact-index ?vid) (engines $?pre [?third-engine] $?post)) => ; 移除第3个引擎 (modify ?vid (engines ?pre ?post)) )
通过索引定位移除:
(defrule remove-engine-by-index (vehicle (fact-index ?vid) (engines $?engine-list)) => (if (> (length$ ?engine-list) 2) then ; 移除第3个元素,拼接前后部分 (bind ?new-list (create$ (nth$ 1 2 ?engine-list) (nth$ 4 (length$ ?engine-list) ?engine-list))) (modify ?vid (engines ?new-list)) ) )
内容的提问来源于stack exchange,提问作者Homunculus Reticulli
相关产品推荐
相关产品推荐

