/usr/share/pyshared/pyke/fc_rule.py is in python-pyke 1.1.1-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | # $Id: fc_rule.py 38124415f0b5 2010-04-21 mtnyogi $
# coding=utf-8
#
# Copyright © 2007-2008 Bruce Frederiksen
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
'''
Forward chaining rules (fc_rule) are one of two types of rules in a
rule_base (the other being backward chaining rules -- bc_rule).
All forward chaining is done automatically as each rule_base is
activated. This is done in two steps:
1. All fc_rules are registered with the fact_lists referenced in
their 'foreach' clause by calling fc_rule.register_rule() on
each fc_rule (including the parent rule_base's fc_rules).
This will cause the fact_list to invoke fc_rule.new_fact each time
a new fact for that fact_list (by that name) is asserted (by the
same or another fc_rule).
2. The fc_rule.run() function is called on each fc_rule (including
the parent rule_base's fc_rules).
The forward chaining rule is compiled into a python function which does
the actual inferencing work for both the 'run' case and the 'new_fact'
case, depending on the arguments passed to it. Each fc_rule object
remembers its associated compiled python function.
The fc_rule object tracks the progress of the forward chaining for that
rule. If the rule has not been run yet, it ignores new_facts since it
will see the new fact when it is later run.
'''
from pyke import contexts, fact_base
import itertools
class rule(object):
''' Common to both fc_rules and bc_rules. '''
def __init__(self, name, rule_base, patterns):
self.name = name
self.rule_base = rule_base
self.patterns = patterns
def __repr__(self):
return "<%s %s>" % (self.__class__.__name__, self.name)
def pattern(self, pattern_index):
return self.patterns[pattern_index]
class fc_rule(rule):
def __init__(self, name, rule_base, rule_fn, foreach_facts, patterns):
super(fc_rule, self).__init__(name, rule_base, patterns)
rule_base.add_fc_rule(self)
self.rule_fn = rule_fn
self.foreach_facts = foreach_facts # (kb_name, fact_name, arg_pats,
# multi_match?)...
self.ran = False
def register_rule(self):
for i, (kb_name, fact_name, arg_patterns, multi_match) \
in enumerate(self.foreach_facts):
self.rule_base.engine.get_kb(kb_name, fact_base.fact_base) \
.add_fc_rule_ref(fact_name, self, i)
def reset(self):
self.ran = False
def run(self):
self.ran = True
self.rule_fn(self)
def new_fact(self, fact_args, n):
if self.ran:
arg_patterns = self.foreach_facts[n][2]
if len(fact_args) == len(arg_patterns):
context = contexts.simple_context()
if all(itertools.imap(lambda pat, arg:
pat.match_data(context, context, arg),
arg_patterns,
fact_args)):
self.rule_base.num_fc_rules_rerun += 1
if self.foreach_facts[n][3]:
self.rule_fn(self)
else:
self.rule_fn(self, context, n)
context.done()
def foreach_patterns(self, foreach_index):
return self.foreach_facts[foreach_index][2]
|