I've run into a bit of an issue with some CLIPSpy code. I've narrowed down the issue to either the encode method of CLIPS_CONSTRUCTS.encode() or the environment.load(constructs_file.name). The goal I'm trying to capture is to fire a rule when the oil temp is above 32 and the oil pressure is above 0. I've attached the SampleData.csv I'm working with. This is part of my thesis research and I'd like to credit all that help me out!
import sys
from tempfile import NamedTemporaryFile
import clips
CLIPS_CONSTRUCTS = """
(deftemplate oil-measure
(slot utc-time (type STRING))
(slot temperature (type INTEGER))
(slot pressure (type INTEGER)))
(defrule oil-is-hot
(oil-measure (temperature ?temp) (utc-time ?time))
(test (> ?temp 32))
=>
(printout t ?time tab "temperature:" tab ?temp crlf))
(defrule pressure-is-high
(oil-measure (pressure ?press&:(> ?press 0)) (utc-time ?time))
=>
(printout t ?time tab "pressure:" tab ?press crlf))
"""
def main():
environment = clips.Environment()
# use environment.load() to load constructs from a file
with NamedTemporaryFile() as constructs_file:
constructs_file.write(CLIPS_CONSTRUCTS.encode())
constructs_file.flush()
environment.load(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_measure_template = environment.find_template("oil-measure")
for time, temp, press in get_data_frames(sys.argv[1]):
new_fact = oil_measure_template.new_fact()
# Template facts are represented as dictionaries
new_fact["utc-time"] = time
new_fact["temperature"] = int(temp)
new_fact["pressure"] = int(press)
# 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()
This is a limitation of NamedTemporaryFile
on Windows documented here.
You can workaround it using mkstemp
or a regular file you remove yourself once done.
constructs_file, constructs_file_name = mkstemp()
constructs_file.write(CLIPS_CONSTRUCTS.encode())
constructs_file.close()
environment.load(constructs_file_name)
os.remove(constructs_file_name)