buguroo / pyknow Goto Github PK
View Code? Open in Web Editor NEWPyKnow: Expert Systems for Python
License: GNU Lesser General Public License v3.0
PyKnow: Expert Systems for Python
License: GNU Lesser General Public License v3.0
STEPS TO REPRODUCE:
Using https://github.com/buguroo/pyknow/blob/develop/docs/examples/maximum.ipynb
watch(watchers.RULES, watchers.FACTS, watchers.ACTIVATIONS)
m.run()
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-4-b1cd45e85340> in <module>
----> 1 watch(watchers.RULES, watchers.FACTS, watchers.ACTIVATIONS)
2 m.run()
~/Documents/github/pyknow/pyknow/pyknow/watchers.py in watch(level, *what)
39
40 for watcher_name in what:
---> 41 watcher = globals()[watcher_name]
42 watcher.setLevel(level)
43
KeyError: <Logger pyknow.watchers.RULES (WARNING)>
Hi,
I am new to PyKnow and I am attempting to make a functionnality that will allow me to load the set of Rules from an external file.
I tried to use set_attr but without success the interpreter doesn't like the RULE decorator. Do you know a manner to do it properly ?
Thank you in advance for your time and consideration
## Extern file
@Rule(Light(color='green'))
def green_light(self):
print("Walk")
@Rule(Light(color='red'))
def red_light(self):
print("Don't walk")
###########################
from pyknow import *
class Light(Fact):
"""Info about the traffic light."""
pass
class RobotCrossStreet(KnowledgeEngine):
# no rules hardcoded
if __name__ == '__main__':
engine = RobotCrossStreet()
engine.reset()
engine.declare(Light(color="green"))
engine.run()
I have implemented following test application for measuring performance of pyknow.
import time
from pyknow import *
class Engine(KnowledgeEngine):
def __init__(self, fact_count, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fact_count = fact_count
self.matched = 0
self.not_matched = 0
@DefFacts()
def _init(self):
for i in range(self.fact_count):
yield Fact(i,i%10)
@Rule(Fact(MATCH.a, MATCH.a))
def rule1(self):
self.matched += 1
@Rule(Fact(MATCH.a, ~MATCH.a))
def rule2(self):
self.not_matched += 1
def run(fact_count):
start = time.time()
e = Engine(fact_count)
e.reset()
e.run()
end = time.time()
print(end - start)
When I run it with following fact counts:
run(10)
run(100)
run(500)
run(1000)
run(10000)
I am getting these results for execution time in seconds:
0.00998544692993164
0.08772945404052734
1.528554916381836
5.943406105041504
742.3850135803223
The problem is that the execution time becomes a bottleneck very quickly in my case when there are around 10000 facts. This was simplified example (and in principle this could be easily implemented without pyknow) but I would think that 10000 facts should not be a big issue when the rules are so simple.
If I remove @Rule(Fact(MATCH.a, ~MATCH.a))
which is fired more often than the other one, then execution time stays quite short (max 11 seconds).
So is this known issue or do I just misunderstanding something?
hi, buguroo.
I have another question about the pyknow.
When I use "&" it can work well and won't go while first option is True.
However . I use "|" it can't work well, while first option is True.
from pyknow import *
class User(Fact):
pass
class BaseRule(KnowledgeEngine):
array = []
@DefFacts()
def get_facts(self):
yield User(d=None)
@Rule(User(d=P(lambda x: x is not None) & P(lambda x: x >= 20)))
def pas(self):
print('pass')
@Rule(User(d=P(lambda x: x is None) | P(lambda x: x >= 20)))
def err(self):
print('error')
engine=BaseRule()
engine.reset()
engine.run()
thanks
Hello,
I can install by pip the module, but in the shell of python 2, I can not import the module. I received:
>>> import pyknow
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/dist-packages/pyknow/__init__.py", line 2, in <module>
from .engine import KnowledgeEngine
File "/usr/local/lib/python2.7/dist-packages/pyknow/engine.py", line 10, in <module>
from pyknow import abstract
File "/usr/local/lib/python2.7/dist-packages/pyknow/abstract.py", line 8
class Matcher(metaclass=abc.ABCMeta):
In python3:
>>> import pyknow
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'pyknow'
in python3.6:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'pyknow'
Error in sys.excepthook:
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/apport_python_hook.py", line 63, in apport_excepthook
from apport.fileutils import likely_packaged, get_recent_crashes
File "/usr/lib/python3/dist-packages/apport/__init__.py", line 5, in <module>
from apport.report import Report
File "/usr/lib/python3/dist-packages/apport/report.py", line 30, in <module>
import apport.fileutils
File "/usr/lib/python3/dist-packages/apport/fileutils.py", line 23, in <module>
from apport.packaging_impl import impl as packaging
File "/usr/lib/python3/dist-packages/apport/packaging_impl.py", line 23, in <module>
import apt
File "/usr/lib/python3/dist-packages/apt/__init__.py", line 23, in <module>
import apt_pkg
ModuleNotFoundError: No module named 'apt_pkg'
Original exception was:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'pyknow'
>>>
Thank you for your effort and kind regards.
Hi Buguroo,
Now I am using Pyknow to do a calculation, and can i ask how to return a value out of pyknow so I can use as part of web application?
Current only print is working.
Thanks
Thank you so much!
This completely fixed my problem. My initialization time went from 12 minutes to 1 second, and my reset time also went from 12 minutes to 1 second. The time to run the engine, declare facts, and reset the engine after it has been run once have all improved from approximately 30 seconds to near instantaneous.
Thank you again and have a nice day!
Originally posted by @ab612 in #7 (comment)
Is there a way for a rule to match against the content of a list (contains or in). In the following example, if parameters is a list and I want to match a bottle that's mentioned in that list, how do i do it?
@freeze.register(list)
def freeze_list(l):
return ";".join(l)
class Bottle(Fact):
name = Field(str, default=None)
class Action(Fact):
name = Field(str, default=None)
parameters = Field(list, default=[])
@Rule(AND(Bottle(name=MATCH.name),
Action(parameters=MATCH.params & CONTAINS(MATCH.name))))
I'm getting the following error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/mbehery/workspace/science/behery2019graph/scripts/world_parser.py", line 95, in <module>
class Kitchen(KnowledgeEngine):
File "/home/mbehery/workspace/science/behery2019graph/scripts/world_parser.py", line 158, in Kitchen
Action(parameters=MATCH.params & CONTAINS(MATCH.name))))
File "/usr/local/lib/python3.6/site-packages/pyknow/operator.py", line 45, in __from_operator2
"A ConditionalElement can't be used as an operator condition.")
TypeError: A ConditionalElement can't be used as an operator condition.
Note: If I match against a string it's working as follows:
@Rule(AND(Bottle(name=MATCH.name),
Action(parameters=MATCH.params & CONTAINS("bottle"))))
As mentioned in #35, we need better documentation on this subject.
Hello,
Your project doesn't exist anymore on PyPi. I don't know if it's wanted or not, but I let this here. I'm trying to build container and Pip crash when it come to install PyKnow from PyPi. And there is a 404 on the project page.
It would be easier if you can do something about it, if not I'll build the container without and do a manual pull from this repo inside the container.
Rules are being called on already retracted facts.
P = [[None, 2, None, 6, None, 8, None, None, None],
[5, 8, None, None, None, 9, 7, None, None],
[None, None, None, None, 4, None, None, None, None],
[3, 7, None, None, None, None, 5, None, None],
[6, None, None, None, None, None, None, None, 4],
[None, None, 8, None, None, None, None, 1, 3],
[None, None, None, None, 2, None, None, None, None],
[None, None, 9, 8, None, None, None, 3, 6],
[None, None, None, 3, None, 6, None, 9, None]]
class Possible(Fact):
pass
class Solver(KnowledgeEngine):
@DefFacts()
def init_puzzle(self):
for x, row in enumerate(P):
for y, cell in enumerate(row):
block = ((y // 3) * 3) + (x // 3)
if cell is None:
yield Fact(value=None, y=y, x=x, block=block)
for i in range(1, 10):
yield Possible(value=i, y=y, x=x, block=block)
else:
yield Fact(value=cell, y=y, x=x, block=block)
@Rule(Fact(value=~L(None) & MATCH.v, y=MATCH.y),
AS.p << Possible(value=MATCH.v, y=MATCH.y))
def discarded_by_column(self, p):
self.retract(p)
@Rule(Fact(value=~L(None) & MATCH.v, x=MATCH.x),
AS.p << Possible(value=MATCH.v, x=MATCH.x))
def discarded_by_row(self, p):
self.retract(p)
@Rule(Fact(value=~L(None) & MATCH.v, block=MATCH.b),
AS.p << Possible(value=MATCH.v, block=MATCH.b))
def discarded_by_block(self, p):
self.retract(p)
@Rule(AS.cell << Fact(value=None, x=MATCH.x, y=MATCH.y, block=MATCH.b),
Possible(value=MATCH.v, x=MATCH.x, y=MATCH.y, block=MATCH.b),
NOT(Possible(value=~MATCH.v, x=MATCH.x, y=MATCH.y, block=MATCH.b)))
def only_one_possible(self, cell, v):
self.retract(cell)
self.declare(Fact(value=v, x=cell['x'], y=cell['y'], block=cell['block']))
@Rule(AS.cell << Fact(value=None, x=MATCH.x, y=MATCH.y, block=MATCH.b),
Possible(value=MATCH.v, x=MATCH.x, y=MATCH.y, block=MATCH.b),
NOT(Possible(value=MATCH.v, x=~MATCH.x, y=~MATCH.y, block=MATCH.b)))
def unique_candidate_block(self, cell, v):
self.retract(cell)
self.declare(Fact(value=v, x=cell['x'], y=cell['y'], block=cell['block']))
@Rule(AS.cell << Fact(value=None, x=MATCH.x, y=MATCH.y, block=MATCH.b),
Possible(value=MATCH.v, x=MATCH.x, y=MATCH.y, block=MATCH.b),
NOT(Possible(value=MATCH.v, x=~MATCH.x, y=MATCH.y, block=~MATCH.b)))
def unique_candidate_col(self, cell, v):
self.retract(cell)
self.declare(Fact(value=v, x=cell['x'], y=cell['y'], block=cell['block']))
@Rule(AS.cell << Fact(value=None, x=MATCH.x, y=MATCH.y, block=MATCH.b),
Possible(value=MATCH.v, x=MATCH.x, y=MATCH.y, block=MATCH.b),
NOT(Possible(value=MATCH.v, x=MATCH.x, y=~MATCH.y, block=~MATCH.b)))
def unique_candidate_row(self, cell, v):
self.retract(cell)
self.declare(Fact(value=v, x=cell['x'], y=cell['y'], block=cell['block']))
@Rule(Fact(value=~L(None) & MATCH.v, x=MATCH.x, y=MATCH.y, block=MATCH.b),
AS.p << Possible(value=~MATCH.v, x=MATCH.x, y=MATCH.y, block=MATCH.b))
def remove_other_candidates(self, p):
self.retract(p)
watch('RULES', 'FACTS')
s = Solver()
s.reset()
s.run()
This code raises the following exception:
INFO:pyknow.watchers.FACTS: <== <f-130>: Possible(value=2, y=1, x=2, block=0)
INFO:pyknow.watchers.RULES:FIRE 531 unique_candidate_col: <f-130>, <f-128>
Traceback (most recent call last):
File "sudoku.py", line 95, in <module>
s.run()
File "/home/nil/.local/share/virtualenvs/sudoku-VtHvu9jk/lib/python3.7/site-packages/pyknow/engine.py", line 168, in run
for k, v in activation.context.items()
File "/home/nil/.local/share/virtualenvs/sudoku-VtHvu9jk/lib/python3.7/site-packages/pyknow/rule.py", line 87, in __call__
return self._wrapped(*args, **kwargs)
File "sudoku.py", line 76, in unique_candidate_col
self.retract(cell)
File "/home/nil/.local/share/virtualenvs/sudoku-VtHvu9jk/lib/python3.7/site-packages/pyknow/engine.py", line 124, in retract
self.facts.retract(idx_or_declared_fact)
File "/home/nil/.local/share/virtualenvs/sudoku-VtHvu9jk/lib/python3.7/site-packages/pyknow/factlist.py", line 111, in retract
raise IndexError('Fact not found.')
IndexError: Fact not found.
A similar exception is raised if the method modify
is used instead of retract
+declare
.
Suppose I have a Message(Fact)
and message can contain both an attachment and a body, both of which share properties, e.g. is_spam
.
It would be lovely to model my facts starting with a att = Text(spam=0)
, and bdy = Text(spam=1)
and then create a Message(att=att, bdy=bdy)
fact.
Is this behavior supported/recommended?
Background, I am new to Pyknow. I want to build a expert system to auto calculate a cell quality score based on some parameters. The score algorithm should be loaded from a json data, such like:
{
"PN": [{
"condition": "pn",
"symbol": "=",
"value": "2PN",
"score": "20",
"weight": "1.0"
}, {
"condition": "time",
"symbol": "<=",
"value": "12",
"score": "20",
"weight": "1.0"
}],
"4C": [{
"condition": "cell",
"symbol": "=",
"value": "4C",
"score": "20",
"weight": "1.0"
}, {
"condition": "even",
"symbol": "=",
"value": true,
"score": "20",
"weight": "1.0"
}, {
"condition": "fragment",
"symbol": "=",
"value": "<5%",
"score": "20",
"weight": "1.0"
}, {
"condition": "fragment",
"symbol": "=",
"value": "5%-10%",
"score": "15",
"weight": "1.0"
}, {
"condition": "fragment",
"symbol": "=",
"value": "10%-20%",
"score": "10",
"weight": "1.0"
}, {
"condition": "time",
"symbol": "<=",
"value": "36",
"score": "20",
"weight": "1.0"
}]
}
Here are my codes for this,
from pyknow import *
from functools import partial
class EmbryoScore(KnowledgeEngine):
score = 0
@classmethod
def removeAllRules(cls):
for m in [attr for attr in cls.__dict__ if attr.startswith('rule')]:
delattr(cls, m)
def parse_json_rules(rule_json):
import json
rules = json.loads(rule_json)
sal = 100
index = 0
for stage in rules:
for rule_item in rules[stage]:
rule = {'condition': rule_item['condition']}
rule['stage'] = stage
if rule_item['symbol'] not in ('=', '<', '<=', '>', '>='):
continue
def _cond(value, symbol):
if symbol == '=': return EQ(value)
if symbol == '<': return LT(value)
if symbol == '<=': return LE(value)
if symbol == '>': return GT(value)
if symbol == '>=': return GE(value)
def _add(self, **kwargs):
if 'score' not in kwargs or 'weight' not in kwargs:
raise ValueError('No score or weight specified')
s, w = int(kwargs['score']), float(kwargs['weight'])
self.score += s * w
R = Rule(AND(Fact(**rule, value=MATCH.value &
_cond(rule_item['value'], rule_item['symbol']))),
salience=sal)(partial(_add, score=rule_item['score'],
weight=rule_item['weight']))
setattr(EmbryoScore, f'rule{index}', R)
index += 1
sal -= 1
def init_engine(rule_json):
EmbryoScore.removeAllRules()
parse_json_rules(rule_json)
engine = EmbryoScore()
engine.reset()
return engine
import unittest
class ScoreTest(unittest.TestCase):
def test(self):
engine = init_engine(rule_json)
engine.declare(Fact(condition='pn', stage='PN', value='2PN'))
engine.declare(Fact(stage='4C', condition='cell', value='4C'))
engine.declare(Fact(stage='4C', condition='fragment', value='10%-20%'))
engine.declare(Fact(stage='4C', condition='time', value='32'))
engine.run()
self.assertEqual(engine.score, 70)
if __name__ == '__main__':
unittest.main()
It raises a AttributeError: 'Rule' object has no attribute 'name' when engine.run() on engine.py line 162
watchers.RULES.info(
"FIRE %s %s: %s",
execution,
activation.rule.__name__,
", ".join(str(f) for f in activation.facts))
I can't find out what the problem is. Wonder if I can get some help here. THANKS.
A multifield wildcard, denoted by a +MATCH.somename
, matches any value in zero or more fields in a pattern entity.
Hi! @nilp0inter, thank you very much for your library, when i use this library i have some questions that i need your help.
here is my code
from pyknow import *
def rule_hk(pat_args=None,arg_dict=None):
for k,v in arg_dict.items():
if pat_args in v:
return True,'some message: {}'.format(v)
return False,'nothing happend'
class Greetings(KnowledgeEngine):
def __init__(self):
super().__init__()
@property
def input_facts(self):
return self._facts
@input_facts.setter
def input_facts(self, facts):
self._facts = facts
@DefFacts()
def _initial_action(self):
for fact in self._facts:
yield fact
def excute(self, facts):
self.input_facts = facts
self.reset()
self.run()
def load_rule_to_engine(rule_dict_list):
for index, rule_dict in enumerate(rule_dict_list):
R = Rule(rule_dict)(return_invalid_msg(ruledata=rule_dict))
setattr(Greetings, f'rule{index}', R)
def return_invalid_msg(ruledata):
def pk_d(self, **kwargs):
print('bingo!')
return ruledata
return pk_d
x = 1
arg_dict = {
'a':[1,2,3],
'b':[7,8,9]
}
Rules = [Fact(hk=P(lambda x: rule_hk(pat_args=x, arg_dict=arg_dict)))]
load_rule_to_engine(Rules)
engine = Greetings()
fact = Fact(hk=1)
facts = [ fact ]
engine.excute(facts)
I want the P return value 'some message:' ๏ผbut it seems that the return value will not be returned after the rule is executed. The return value just seems to be used to determine whether the rule is hitting. Can P returnvalue appear in return_invalid_msg function? How can i do ๏ผ(very sorry for my bad english)
Thanks๏ผ
Hi, your project pyknow requires "schema==0.6.7" in its dependency. After analyzing the source code, we found that the following versions of schema can also be suitable without affecting your project, i.e., schema 0.5.0, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.6.4, 0.6.5, 0.6.6, 0.6.8. Therefore, we suggest to loosen the dependency on schema from "schema==0.6.7" to "schema>=0.5.0,<=0.6.8" to avoid any possible conflict for importing more packages or for downstream projects that may use pyknow.
May I pull a request to further loosen the dependency on schema?
By the way, could you please tell us whether such dependency analysis may be potentially helpful for maintaining dependencies easier during your development?
We also give our detailed analysis as follows for your reference:
Your project pyknow directly uses 1 APIs from package schema.
schema.Schema.__init__
Beginning from the 1 APIs above, -1 functions are then indirectly called, including -1 schema's internal APIs and 0 outsider APIs. The specific call graph is listed as follows (neglecting some repeated function occurrences).
[/buguroo/pyknow]
+--schema.Schema.__init__
We scan schema's versions and observe that during its evolution between any version from [0.5.0, 0.6.0, 0.6.1, 0.6.2, 0.6.3, 0.6.4, 0.6.5, 0.6.6, 0.6.8] and 0.6.7, the changing functions (diffs being listed below) have none intersection with any function or API we mentioned above (either directly or indirectly called by this project).
diff: 0.6.7(original) 0.5.0
['schema.schema.SchemaError.code', 'schema.schema.Const.validate', 'schema.test_schema.test_dict_key_error', 'schema.test_schema.test_strictly', 'schema.schema.Optional.__hash__', 'schema.schema.SchemaForbiddenKeyError', 'schema.schema.And.validate', 'schema.schema.SchemaUnexpectedTypeError', 'schema.schema.Regex.validate', 'schema.test_schema.test_inheritance', 'schema.test_schema.test_schema_repr', 'schema.test_schema.test_ignore_extra_keys_validation_and_return_keys', 'schema.test_schema.test_schema_error_handling', 'schema.schema.Const', 'schema.test_schema.test_dict', 'schema.test_schema.test_ignore_extra_keys', 'schema.schema.Optional', 'schema.schema.Use', 'schema.test_schema.test_issue_9_prioritized_key_comparison_in_dicts', 'schema.schema.Regex.__init__', 'schema.test_schema.test_and_error_handling', 'schema.schema.Regex.__repr__', 'schema.test_schema.test_or_error_handling', 'schema.test_schema.ve', 'schema.schema.And.__init__', 'schema.test_schema.test_issue_56_cant_rely_on_callables_to_have_name', 'schema.test_schema.test_regex', 'schema.schema.Or', 'schema.test_schema.test_optional_key_convert_failed_randomly_while_with_another_optional_object', 'schema.schema.And', 'schema.schema.Or.validate', 'schema.schema.Forbidden.__init__', 'schema.test_schema.test_issue_9_prioritized_key_comparison', 'schema.test_schema.test_missing_keys_exception_with_non_str_dict_keys', 'schema.test_schema.test_validate_list', 'schema.test_schema.test_dict_keys', 'schema.test_schema.test_copy', 'schema.schema.SchemaMissingKeyError', 'schema.test_schema.se', 'schema.test_schema.test_complex', 'schema.test_schema.test_validate_object', 'schema.test_schema.test_dict_forbidden_keys', 'schema.schema.SchemaError', 'schema.test_schema.test_dict_subtypes', 'schema.schema.Forbidden', 'schema.schema.SchemaWrongKeyError', 'schema.test_schema.test_or', 'schema.test_schema.test_use_error_handling', 'schema.test_schema.test_validate_file', 'schema.test_schema.test_error_reporting', 'schema.schema.Regex', 'schema.test_schema.test_schema', 'schema.schema.Use.validate', 'schema.test_schema.test_nice_errors', 'schema.schema.Schema._dict_key_priority', 'schema.test_schema.test_exception_handling_with_bad_validators', 'schema.test_schema.test_and', 'schema.test_schema.test_dict_optional_keys', 'schema.schema.Schema.validate', 'schema.schema.Schema', 'schema.test_schema.test_issue_83_iterable_validation_return_type', 'schema.test_schema.test_list_tuple_set_frozenset', 'schema.test_schema.test_test', 'schema.test_schema.test_dict_optional_defaults', 'schema.schema.Optional.__eq__', 'schema.schema.SchemaError.__init__', 'schema.test_schema.test_use_json']
diff: 0.6.7(original) 0.6.0
['schema.schema.SchemaError.code', 'schema.schema.Const.validate', 'schema.test_schema.test_dict_key_error', 'schema.test_schema.test_strictly', 'schema.schema.Optional.__hash__', 'schema.schema.SchemaForbiddenKeyError', 'schema.schema.And.validate', 'schema.schema.SchemaUnexpectedTypeError', 'schema.schema.Regex.validate', 'schema.test_schema.test_inheritance', 'schema.test_schema.test_schema_repr', 'schema.test_schema.test_ignore_extra_keys_validation_and_return_keys', 'schema.test_schema.test_schema_error_handling', 'schema.schema.Const', 'schema.test_schema.test_dict', 'schema.test_schema.test_ignore_extra_keys', 'schema.schema.Optional', 'schema.schema.Use', 'schema.test_schema.test_issue_9_prioritized_key_comparison_in_dicts', 'schema.test_schema.test_and_error_handling', 'schema.test_schema.test_or_error_handling', 'schema.test_schema.ve', 'schema.schema.And.__init__', 'schema.test_schema.test_issue_56_cant_rely_on_callables_to_have_name', 'schema.test_schema.test_regex', 'schema.schema.Or', 'schema.test_schema.test_optional_key_convert_failed_randomly_while_with_another_optional_object', 'schema.schema.And', 'schema.schema.Or.validate', 'schema.schema.Forbidden.__init__', 'schema.test_schema.test_issue_9_prioritized_key_comparison', 'schema.test_schema.test_missing_keys_exception_with_non_str_dict_keys', 'schema.test_schema.test_validate_list', 'schema.test_schema.test_dict_keys', 'schema.test_schema.test_copy', 'schema.schema.SchemaMissingKeyError', 'schema.test_schema.se', 'schema.test_schema.test_complex', 'schema.test_schema.test_validate_object', 'schema.test_schema.test_dict_forbidden_keys', 'schema.schema.SchemaError', 'schema.test_schema.test_dict_subtypes', 'schema.schema.Forbidden', 'schema.schema.SchemaWrongKeyError', 'schema.test_schema.test_or', 'schema.test_schema.test_use_error_handling', 'schema.test_schema.test_validate_file', 'schema.test_schema.test_error_reporting', 'schema.schema.Regex', 'schema.test_schema.test_schema', 'schema.schema.Use.validate', 'schema.test_schema.test_nice_errors', 'schema.schema.Schema._dict_key_priority', 'schema.test_schema.test_exception_handling_with_bad_validators', 'schema.test_schema.test_and', 'schema.test_schema.test_dict_optional_keys', 'schema.schema.Schema.validate', 'schema.schema.Schema', 'schema.test_schema.test_issue_83_iterable_validation_return_type', 'schema.test_schema.test_list_tuple_set_frozenset', 'schema.test_schema.test_test', 'schema.test_schema.test_dict_optional_defaults', 'schema.schema.Optional.__eq__', 'schema.schema.SchemaError.__init__', 'schema.test_schema.test_use_json']
diff: 0.6.7(original) 0.6.1
['schema.schema.SchemaError.code', 'schema.schema.Const.validate', 'schema.test_schema.test_dict_key_error', 'schema.test_schema.test_strictly', 'schema.schema.Optional.__hash__', 'schema.schema.SchemaForbiddenKeyError', 'schema.schema.And.validate', 'schema.schema.SchemaUnexpectedTypeError', 'schema.schema.Regex.validate', 'schema.test_schema.test_inheritance', 'schema.test_schema.test_schema_repr', 'schema.test_schema.test_ignore_extra_keys_validation_and_return_keys', 'schema.test_schema.test_schema_error_handling', 'schema.schema.Const', 'schema.test_schema.test_dict', 'schema.test_schema.test_ignore_extra_keys', 'schema.schema.Optional', 'schema.schema.Use', 'schema.test_schema.test_issue_9_prioritized_key_comparison_in_dicts', 'schema.test_schema.test_and_error_handling', 'schema.test_schema.test_or_error_handling', 'schema.test_schema.ve', 'schema.schema.And.__init__', 'schema.test_schema.test_issue_56_cant_rely_on_callables_to_have_name', 'schema.test_schema.test_regex', 'schema.schema.Or', 'schema.test_schema.test_optional_key_convert_failed_randomly_while_with_another_optional_object', 'schema.schema.And', 'schema.schema.Or.validate', 'schema.schema.Forbidden.__init__', 'schema.test_schema.test_issue_9_prioritized_key_comparison', 'schema.test_schema.test_missing_keys_exception_with_non_str_dict_keys', 'schema.test_schema.test_validate_list', 'schema.test_schema.test_dict_keys', 'schema.test_schema.test_copy', 'schema.schema.SchemaMissingKeyError', 'schema.test_schema.se', 'schema.test_schema.test_complex', 'schema.test_schema.test_validate_object', 'schema.test_schema.test_dict_forbidden_keys', 'schema.schema.SchemaError', 'schema.test_schema.test_dict_subtypes', 'schema.schema.Forbidden', 'schema.schema.SchemaWrongKeyError', 'schema.test_schema.test_or', 'schema.test_schema.test_use_error_handling', 'schema.test_schema.test_validate_file', 'schema.test_schema.test_error_reporting', 'schema.schema.Regex', 'schema.test_schema.test_schema', 'schema.schema.Use.validate', 'schema.test_schema.test_nice_errors', 'schema.schema.Schema._dict_key_priority', 'schema.test_schema.test_exception_handling_with_bad_validators', 'schema.test_schema.test_and', 'schema.test_schema.test_dict_optional_keys', 'schema.schema.Schema.validate', 'schema.schema.Schema', 'schema.test_schema.test_issue_83_iterable_validation_return_type', 'schema.test_schema.test_list_tuple_set_frozenset', 'schema.test_schema.test_test', 'schema.test_schema.test_dict_optional_defaults', 'schema.schema.Optional.__eq__', 'schema.schema.SchemaError.__init__', 'schema.test_schema.test_use_json']
diff: 0.6.7(original) 0.6.2
['schema.schema.SchemaError.code', 'schema.schema.Const.validate', 'schema.test_schema.test_dict_key_error', 'schema.test_schema.test_strictly', 'schema.schema.Optional.__hash__', 'schema.schema.SchemaForbiddenKeyError', 'schema.schema.And.validate', 'schema.schema.SchemaUnexpectedTypeError', 'schema.schema.Regex.validate', 'schema.test_schema.test_inheritance', 'schema.test_schema.test_schema_repr', 'schema.test_schema.test_ignore_extra_keys_validation_and_return_keys', 'schema.test_schema.test_schema_error_handling', 'schema.schema.Const', 'schema.test_schema.test_dict', 'schema.test_schema.test_ignore_extra_keys', 'schema.schema.Optional', 'schema.schema.Use', 'schema.test_schema.test_issue_9_prioritized_key_comparison_in_dicts', 'schema.test_schema.test_and_error_handling', 'schema.test_schema.test_or_error_handling', 'schema.test_schema.ve', 'schema.schema.And.__init__', 'schema.test_schema.test_issue_56_cant_rely_on_callables_to_have_name', 'schema.test_schema.test_regex', 'schema.schema.Or', 'schema.test_schema.test_optional_key_convert_failed_randomly_while_with_another_optional_object', 'schema.schema.And', 'schema.schema.Or.validate', 'schema.schema.Forbidden.__init__', 'schema.test_schema.test_issue_9_prioritized_key_comparison', 'schema.test_schema.test_missing_keys_exception_with_non_str_dict_keys', 'schema.test_schema.test_validate_list', 'schema.test_schema.test_dict_keys', 'schema.test_schema.test_copy', 'schema.schema.SchemaMissingKeyError', 'schema.test_schema.se', 'schema.test_schema.test_complex', 'schema.test_schema.test_validate_object', 'schema.test_schema.test_dict_forbidden_keys', 'schema.schema.SchemaError', 'schema.test_schema.test_dict_subtypes', 'schema.schema.Forbidden', 'schema.schema.SchemaWrongKeyError', 'schema.test_schema.test_or', 'schema.test_schema.test_use_error_handling', 'schema.test_schema.test_validate_file', 'schema.test_schema.test_error_reporting', 'schema.schema.Regex', 'schema.test_schema.test_schema', 'schema.schema.Use.validate', 'schema.test_schema.test_nice_errors', 'schema.schema.Schema._dict_key_priority', 'schema.test_schema.test_exception_handling_with_bad_validators', 'schema.test_schema.test_and', 'schema.test_schema.test_dict_optional_keys', 'schema.schema.Schema.validate', 'schema.schema.Schema', 'schema.test_schema.test_issue_83_iterable_validation_return_type', 'schema.test_schema.test_list_tuple_set_frozenset', 'schema.test_schema.test_test', 'schema.test_schema.test_dict_optional_defaults', 'schema.schema.Optional.__eq__', 'schema.schema.SchemaError.__init__', 'schema.test_schema.test_use_json']
diff: 0.6.7(original) 0.6.3
['schema.schema.Const.validate', 'schema.test_schema.test_dict_key_error', 'schema.schema.Optional.__hash__', 'schema.schema.SchemaForbiddenKeyError', 'schema.schema.And.validate', 'schema.test_schema.test_inheritance', 'schema.test_schema.test_ignore_extra_keys_validation_and_return_keys', 'schema.schema.Const', 'schema.test_schema.test_ignore_extra_keys', 'schema.schema.Optional', 'schema.schema.And.__init__', 'schema.schema.Or', 'schema.schema.And', 'schema.schema.Or.validate', 'schema.schema.Forbidden.__init__', 'schema.test_schema.test_copy', 'schema.test_schema.test_dict_forbidden_keys', 'schema.schema.SchemaError', 'schema.schema.Forbidden', 'schema.schema.Schema._dict_key_priority', 'schema.test_schema.test_dict_optional_keys', 'schema.schema.Schema.validate', 'schema.schema.Schema', 'schema.test_schema.test_test', 'schema.schema.Optional.__eq__', 'schema.schema.SchemaError.__init__']
diff: 0.6.7(original) 0.6.4
['schema.schema.Const.validate', 'schema.test_schema.test_dict_key_error', 'schema.schema.Optional.__hash__', 'schema.schema.SchemaForbiddenKeyError', 'schema.schema.And.validate', 'schema.test_schema.test_inheritance', 'schema.test_schema.test_ignore_extra_keys_validation_and_return_keys', 'schema.schema.Const', 'schema.test_schema.test_ignore_extra_keys', 'schema.schema.Optional', 'schema.schema.And.__init__', 'schema.schema.Or', 'schema.schema.And', 'schema.schema.Or.validate', 'schema.schema.Forbidden.__init__', 'schema.test_schema.test_copy', 'schema.test_schema.test_dict_forbidden_keys', 'schema.schema.SchemaError', 'schema.schema.Forbidden', 'schema.schema.Schema._dict_key_priority', 'schema.test_schema.test_dict_optional_keys', 'schema.schema.Schema.validate', 'schema.schema.Schema', 'schema.test_schema.test_test', 'schema.schema.Optional.__eq__', 'schema.schema.SchemaError.__init__']
diff: 0.6.7(original) 0.6.5
['schema.schema.Const.validate', 'schema.test_schema.test_dict_key_error', 'schema.schema.Optional.__hash__', 'schema.schema.SchemaForbiddenKeyError', 'schema.schema.And.validate', 'schema.test_schema.test_inheritance', 'schema.test_schema.test_ignore_extra_keys_validation_and_return_keys', 'schema.schema.Const', 'schema.test_schema.test_ignore_extra_keys', 'schema.schema.Optional', 'schema.schema.And.__init__', 'schema.schema.Or', 'schema.schema.And', 'schema.schema.Or.validate', 'schema.schema.Forbidden.__init__', 'schema.test_schema.test_dict_forbidden_keys', 'schema.schema.Forbidden', 'schema.schema.Schema._dict_key_priority', 'schema.test_schema.test_dict_optional_keys', 'schema.schema.Schema.validate', 'schema.schema.Schema', 'schema.test_schema.test_test', 'schema.schema.Optional.__eq__']
diff: 0.6.7(original) 0.6.6
['schema.schema.Schema._dict_key_priority', 'schema.schema.Optional', 'schema.schema.Const.validate', 'schema.test_schema.test_dict_optional_keys', 'schema.schema.SchemaMissingKeyError', 'schema.schema.Optional.__hash__', 'schema.schema.Schema.validate', 'schema.schema.SchemaForbiddenKeyError', 'schema.schema.Schema', 'schema.test_schema.test_dict_forbidden_keys', 'schema.test_schema.test_test', 'schema.schema.Forbidden.__init__', 'schema.schema.Forbidden', 'schema.schema.Const', 'schema.schema.Optional.__eq__']
diff: 0.6.7(original) 0.6.8
['schema.schema.SchemaMissingKeyError', 'schema.schema.Or', 'schema.schema.Schema', 'schema.schema.Or.validate', 'schema.schema.Schema.is_valid']
Therefore, we believe that it is quite safe to loose your dependency on schema from "schema==0.6.7" to "schema>=0.5.0,<=0.6.8". This will improve the applicability of pyknow and reduce the possibility of any further dependency conflict with other projects.
Hi
I want to declare new facts in rule RHS. Is there an example of this?
Thanks!
Wondering if there's any way to implement an explanation module to show reasoning to the end user and if there's any utility in the framework to make it straightforward.
Our dependencies (schema and frozendict) are stable and small enough to be included within the source code of pyknow.
Including dependencies along with the project source eliminate danger of interdependency version conflict and guarantee that the exact dependency version is tested with the project.
Hi,
I want to export and import the rules from some JSON format or XML format to PyKnow engine.
I wan to create the UI on top of it to allow user to edit the rules and facts. I was thinking of writing custom parser on top of the rules files
Any help will be appreciated.
Thanks
The construction "label" << W() should issue a DeprecationWarning and disappear in v2.0.0.
The usage of multiple ORFC is causing a combinatorial explosion in the RETE matcher as discovered on #7.
Dear Authors,
I find this module is very promising and I loved the way it works. I had a quick question as to how I can externalize the rules into file. The idea is to extend he flexibility to the user so that he can help himself to decide what rule criteria and matching inference should be...
Any directions in that respect? BTW, I would love to see this fantastic toolkit get some more attention in the python community... I am more than happy to help in anyway I can.
Thanks,
Tharma
from pyknow import *
results in a SyntaxError in python 2.7.6
File "/usr/local/lib/python2.7/dist-packages/pyknow/abstract.py", line 8
class Matcher(metaclass=abc.ABCMeta):
^
SyntaxError: invalid syntax
please let me know if this is considered a bug (i.e is python 2.7 supported)
thanks for your assistance,
sinai
Hi,
I am using PyKnow in my school, the problem I have is how to get the current time in Pyknow. I am using Jupyter notebook
Thanks!
it seems I can only do such things like this:
class RobotCrossStreet(KnowledgeEngine):
@Rule('num' << NumberClass(amount=1000) ))
def cautious(self, num):
if(num>100)
doge(num)
else
dolte(num)
This might not be the best place to ask this , but how do I return results. e.g
The greeting example .....
http://pyknow.readthedocs.io/en/stable/thebasics.html#knowledgeengine
Assuming I wasnt to call the greeting class and pass it data .... Then get results.
e.g greeter = Greeting()
greeter.resulsts ... # I know that method does not exist
Hi,
I am new to PyKnow and I would like to know if it is possible to create multiple knowledge
engines and swap to them like a kind of focus command in CLIPS.
https://www.csie.ntu.edu.tw/~sylee/courses/clips/bpg/node10.6.html
Thank you in advance for your consideration.
On ConflictSetMemory class, the following attributes should be sets:
pyknow/pyknow/matchers/rete/nodes.py
Lines 253 to 254 in 1aed48f
pyknow/pyknow/matchers/rete/nodes.py
Line 260 in 1aed48f
The point is to make search O(1) and improve performance when the same rule has multiple activations like on #12 .
The template system will allow Fact
subclasses to have a schema. A schema is a set of fields names and associates types, allowing the engine to validate facts structure.
I want to use an array in class Fact as a value, But it raise an TypeError
File "/usr/local/lib/python3.6/site-packages/pyknow/engine.py", line 206, in __declare
last_inserted = self.facts.declare(fact)
File "/usr/local/lib/python3.6/site-packages/pyknow/factlist.py", line 69, in declare
fact_id = self._get_fact_id(fact)
File "/usr/local/lib/python3.6/site-packages/pyknow/factlist.py", line 47, in _get_fact_id
for k, v in fact.items()
TypeError: unhashable type: 'list'
it seems that python3 frozenset() unsupport unhashable type
How can I avoid it , thx~
Inline with fuzzyClips, fuzzy extensions to facts please.
Hi! I am trying to use pyknow to my application to fire the rule according to my facts. I have followed the pyknow rule creation process to create my rules. But the problem is when I run the application, it is taking the infinite time to execute. For example, I ran the application last night and it is still in running process now. But if I just remove pyknow it is running and working. I am doing it in pycharm and not getting the idea why is it taking so much time. I have found that it is not because of the rules what I written, it is because of the import line code " from pyknow import * ". Could you please suggest me why this is happening?
Hello,
Thank you for developing this module. I was very excited when I first found it. Currently, I am trying to develop a forecasting tool using it. However, I've noticed that the creation and initial reset of a Knowledge Engine takes a lot of time. About 25 minuets for 10 fact classes and around 30 rules (on a very average computer). Is this to be expected? Please let me know. I have a feeling I'm missing something.
Thank you & Keep up the good work!
Madison S
I checked the source code for creating OrdinaryMatchNode at https://github.com/buguroo/pyknow/blob/develop/pyknow/matchers/rete/utils.py#L167-L186
And compared it to the paper's figure 2.2(a) (matched for C1^C2).
Is it needed for creating a shared OrdinaryMatchNode If two conjunctive normal form has the same facts?
for example,
Rule(OR(AND(Fact(a=1), Fact(b=2), Fact(c=3)), AND(Fact(a=1), Fact(b=2), Fact(c=4))))
It seems that two OrdinaryMatchNode node for (Fact(a=1), Fact(b=2))
will be created.
Is it right?
or should we need a same OrdinaryMatchNode for (Fact(a=1), Fact(b=2))
?
Hi I'm trying to use pyknow. I'm able to declare facts with no problems, but I'm unable to retract them
I'm using the following code:
class bound(Fact):
obj = Field(str, default=None)
manip = Field(str, default="arm")\
class Kitchen(KnowledgeEngine):
""" some code goes here """
pass
kitchen = Kitchen()
kitchen.reset()
kitchen.declare(bound(obj="bottle", manip="arm"))
kitchen.retract(bound(obj="bottle", manip="arm"))
But I'm getting an IndexError
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/site-packages/pyknow/engine.py", line 124, in retract
self.facts.retract(idx_or_declared_fact)
File "/usr/local/lib/python3.6/site-packages/pyknow/factlist.py", line 111, in retract
raise IndexError('Fact not found.')
IndexError: Fact not found.
If I retract using the index it's working fine, but the documentation says:
Both, the index and the fact can be used with retract
Am I missing something here?
Thanks :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.