CLIPSNET中如何按名称从deftemplate获取槽名或槽列表
问题解答
以下是针对CLIPSNET动态遍历事实相关问题的明确答复:
通过deftemplate名称获取模板信息的支持情况
原生CLIPSNET已经提供对应能力,直接调用ClipsEnvironment实例的FindDeftemplate方法,传入deftemplate名称字符串即可获取对应的Deftemplate对象。调用该对象的GetSlotNames()方法就能直接拿到模板下定义的所有槽名集合,不需要提前硬编码槽名常量。通过FactAddressValue获取对应模板信息的支持情况
FactAddressValue类型本身暴露了Deftemplate属性,直接访问该属性就能拿到当前事实关联的Deftemplate实例,后续同样可以通过GetSlotNames()方法获取所有槽的定义。是否需要扩展CLIPSCLRWrapper
不需要。上述能力都是CLIPSNET原生封装层直接开放的公共API,不需要修改、扩展CLIPSCLRWrapper就能实现动态遍历任意模板事实所有槽值的逻辑。
无硬编码槽名的参考实现如下:
List<FactAddressValue> resultValues = clipsEnv.FindAllFacts(resultName); // 优先通过模板名直接查询模板对象,可提前做非空校验避免非法入参 Deftemplate targetTemplate = clipsEnv.FindDeftemplate(resultName); if (targetTemplate == null) { Console.WriteLine($"指定模板{resultName}不存在"); return; } List<string> slotNames = targetTemplate.GetSlotNames().ToList(); foreach (FactAddressValue resultValue in resultValues) { foreach (string slotName in slotNames) { var slotValue = resultValue.GetSlotValue(slotName); Console.WriteLine($"[{slotName}] = {slotValue}"); } }
注意:如果存在事实已被撤销、模板被销毁的边界场景,优先使用
FindDeftemplate提前获取模板对象做校验,比从单个FactAddressValue实例读取Deftemplate属性的鲁棒性更好。
- 用Instances替代Facts是否能简化实现
不会带来本质简化。CLIPSNET中对COOL实例的操作逻辑和事实基本对齐:需要调用FindDefclass获取类定义,再通过类定义的GetSlotNames()拿槽名集合,InstanceValue实例也可以直接访问关联的Defclass属性,整体流程和操作Fact完全一致,不会减少代码量。除非业务建模本身更适合用面向对象的COOL结构,否则不需要为了动态遍历槽的需求特意切换到Instances。
内容的提问来源于stack exchange,提问作者Ken Dellinger
相关产品推荐
相关产品推荐

