This file is indexed.

/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]