Использование логики и в клипах
Я изменил некоторый код CLIPS/CLIPSpy, чтобы искать, когда столбец Variable в CSV - это слово Oil Temp и когда продолжительность этого столбца превышает 600 или выше. Правило должно срабатывать дважды в соответствии с CSV, который я использую:
Вот мой код в настоящее время. Я думаю, что это терпит неудачу на проверке переменной или логической и проверке.
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 ответ
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
требует двойных кавычек "
,
Тем не менее, я бы посоветовал вам использовать альфа-сетевое согласование движка, которое является более кратким и эффективным.
(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
Слот является константой и может соответствующим образом оптимизировать логику сопоставления. Я не уверен, что он может сделать то же самое в рамках совместного испытания.