使用逻辑和CLIPS

时间:2019-01-17 00:42:43

标签: python clips clipspy

我更改了一些CLIPS / CLIPSpy代码,以查找CSV中的“变量”列为“油温”一词以及该列的持续时间是否大于600或更高。该规则应根据我使用的CSV触发两次:
Sample Data

我收到以下错误。
Error

这是我当前的代码。我认为在变量检查或逻辑和检查上都失败了。

import sys
from tempfile import mkstemp
import os
import clips


CLIPS_CONSTRUCTS = """
(defglobal ?*oil-too-hot-times* = 0)

(deftemplate oil-is-too-hot-too-long
  (slot Variable (type STRING))  
  (slot Duration (type INTEGER)))

(defrule check-for-hot-oil-too-long-warning
  (oil-is-too-hot-too-long (Variable ?variable) (Duration ?duration))
  (test (?variable Oil Temp))
  (and (>= ?duration 600))
  =>
  (printout t "Warning! Check engine light on!" tab ?*oil-too-hot-times* crlf)) 

"""


def main():
    environment = clips.Environment()

    # use environment.load() to load constructs from a file
    constructs_file, constructs_file_name = mkstemp()
    file = open(constructs_file, 'wb')
    file.write(CLIPS_CONSTRUCTS.encode())
    file.close()

    environment.load(constructs_file_name)
    os.remove(constructs_file_name)

    # enable fact duplication as data has duplicates
    environment.eval("(set-fact-duplication TRUE)")


    # Template facts can be built from their deftemplate
    oil_too_hot_too_long_template = environment.find_template("oil-is-too-hot-too-long")

    for variable, duration in get_data_frames(sys.argv[1]):
        new_fact = oil_too_hot_too_long_template.new_fact()

        # Template facts are represented as dictionaries
        new_fact["Variable"] = variable
        new_fact["Duration"] = int(duration)

        # Add the fact into the environment Knowledge Base
        new_fact.assertit()

    # Fire all the rules which got activated
    environment.run()

def get_data_frames(file_path):
    """Parse a CSV file returning the dataframes."""
    with open(file_path) as data_file:
        return [l.strip().split(",") for i, l in enumerate(data_file) if i > 1]


if __name__ == "__main__":
    main()

1 个答案:

答案 0 :(得分:1)

CLIPS采用波兰语/前缀表示法。因此,您的规则应如下所示。

(defrule check-for-hot-oil-too-long-warning
  (oil-is-too-hot-too-long (Variable ?variable) (Duration ?duration))
  (test (and (eq ?variable "Oil Temp") 
             (>= ?duration 600)))
  =>
  (printout t "Warning! Check engine light on!" tab ?*oil-too-hot-times* crlf)) 

还要注意类型STRING如何需要双引号"

但是,我建议您利用引擎的Alpha网络匹配,它更加简洁高效。

(defrule check-for-hot-oil-too-long-warning
  (oil-is-too-hot-too-long (Variable "Oil Temp") (Duration ?duration))
  (test (>= ?duration 600))
  =>
  (printout t "Warning! Check engine light on!" tab ?*oil-too-hot-times* crlf)) 

引擎可以立即看到您的Variable插槽是一个常数,并且可以相应地优化匹配逻辑。我不确定在联合测试中是否可以做出相同的假设。