首页> 疑难解答

CLIPS:检查多个事实

withpy 2021-06-19

简介让我们考虑下一个简单的模板:( deftemplate person(ssn?s))我想检查一下,如果一个人“已注册”,没有其他人拥有相同的ssn,但是,我尝试了一些东西......

让我们考虑下一个简单的模板:

(deftemplate person (ssn ?s))

我想检查一下,如果一个人“注册”,没有其他人有相同的ssn,但是,我尝试过类似的东西:

(defrule repeated-person
     (person (ssn ?s1))
     (person (ssn ?s2))
     (test (= ?s1 ?s2))
  =>
     (printout t "No, no, no..." clrf))

甚至,

(defrule repeated-person
     (person (ssn ?s))
     (person (ssn ?s))
  =>
     (printout t "No, no, no..." clrf))

但它不起作用。

我怎么能做到这样的事情?

1
投票

默认情况下,您无法创建重复的事实:

         CLIPS (6.31 2/3/18)
CLIPS> 
(deftemplate person
   (slot SSN))
CLIPS> (assert (person (SSN 123-45-6789)))
<Fact-1>
CLIPS> (facts)
f-0     (initial-fact)
f-1     (person (SSN 123-45-6789))
For a total of 2 facts.
CLIPS> (assert (person (SSN 123-45-6789)))
FALSE
CLIPS> (facts)
f-0     (initial-fact)
f-1     (person (SSN 123-45-6789))
For a total of 2 facts.
CLIPS> 

您可以使用set-fact-duplication函数更改此行为:

CLIPS> (set-fact-duplication TRUE)
FALSE
CLIPS> (assert (person (SSN 123-45-6789)))
<Fact-2>
CLIPS> (facts)
f-0     (initial-fact)
f-1     (person (SSN 123-45-6789))
f-2     (person (SSN 123-45-6789))
For a total of 3 facts.
CLIPS>

然后,您可以编写一个规则,检查是否存在具有相同SSN的两个不同事实:

CLIPS> 
(defrule repeated-person
   ?f1 <- (person (SSN ?ss))
   ?f2 <- (person (SSN ?ss))
   (test (< (fact-index ?f1) (fact-index ?f2)))
   =>
   (printout t "Duplicated SSN " ?ss crlf))
CLIPS> (agenda)
0      repeated-person: f-1,f-2
For a total of 1 activation.
CLIPS>

由于每个事实具有唯一的事实索引,因此测试条件元素中的比较确保匹配第一和第二模式的事实不相同。

如果我们添加另一个具有相同SSN的人,我们将获得该规则的多个激活:

CLIPS> (assert (person (SSN 123-45-6789)))
<Fact-3>
CLIPS> (agenda)
0      repeated-person: f-1,f-3
0      repeated-person: f-2,f-3
0      repeated-person: f-1,f-2
For a total of 3 activations.
CLIPS>

我们可以为每个创建的事实动态分配一个唯一的id,即使在禁用事实重复时也允许创建“重复”事实:

CLIPS> (clear)
CLIPS> (set-fact-duplication FALSE)
TRUE
CLIPS> 
(deftemplate person
   (slot id (default-dynamic (gensym*)))
   (slot SSN))
CLIPS> (assert (person (SSN 123-45-6789)))
<Fact-1>
CLIPS> (assert (person (SSN 123-45-6789)))
<Fact-2>
CLIPS> (assert (person (SSN 123-45-6789)))
<Fact-3>
CLIPS> (facts)
f-0     (initial-fact)
f-1     (person (id gen1) (SSN 123-45-6789))
f-2     (person (id gen2) (SSN 123-45-6789))
f-3     (person (id gen3) (SSN 123-45-6789))
For a total of 4 facts.
CLIPS>

然后,我们可以创建一个规则来打印单个消息,而不管具有相同SSN的人数是多少:

CLIPS> 
(defrule repeated-person
   (person (id ?id) (SSN ?ssn))
   (not (person (id ?id2&:(< (str-compare ?id2 ?id) 0)) (SSN ?ssn)))
   (exists (person (id ~?id) (SSN ?ssn)))
   =>
   (printout t "Duplicated SSN " ?ssn crlf))
CLIPS> (agenda)
0      repeated-person: f-1,*,*
For a total of 1 activation.
CLIPS> (run)
Duplicated SSN 123-45-6789
CLIPS>

上一篇:使用echo模块时的Ansible映射值问题

下一篇:该行在MySQL中没有得到DELETED,PHP没有返回任何错误

相关文章

  • 使用maven自动部署使用maven保存Netbeans entreprise项目

    我有一个NetBeans mavenized项目Contaning:web项目(war)ejb项目(jar)父项目maven项目每次更改后我必须清理构建maven项目并运行Parent ...

  • pyspark会话是否存在spark.implicits?

    我问的也许是一个愚蠢的问题。尽管如此:对于pyspark会话是否存在spark.implicits._如果存在,我该如何导入它们?

  • 如何在HTTP标头中转义换行符?

    在HTTP标头中,换行符是用于分隔标题中的字段的标记。但是,如果我不想在自定义字段中发送换行字符,我应该如何逃避呢?

  • 无法将主swift类导入测试目标?

    我正在尝试在我的iOS应用程序中测试这些类。我试图在我的应用程序中将目标Pickle导入我的测试目标PickleTests,将我的所有类添加到我的测试目标PickleTests中...

  • C#revit api在Revit中创建面板

    我是新来的修改api。我想在revit空项目中创建一个面板。我可以创造墙壁。我想知道如何在墙上添加面板数据(螺柱,面板名称,开口等)。我也是新人...

  • Spring安全性仅显示登录页面的标题

    我一直在和这个人摔跤。我有一个Web应用程序,我正在尝试将Spring Security放入其中。我成功地做到了这一点,每当用户试图访问他们的页面时......