This file is indexed.

/usr/lib/python2.7/dist-packages/swap/update.py is in python-swap 1.2.1-7.

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
""" Update for cwm architecture

The update module provides for the deletion as well as the addition of information to
a formula.  This module assumes the llyn.py store.  It connects intimiately with the
query module.

2004-03-17 written as an extension of query.py
"""


from set_importer import Set, sorted

import diag
from diag import chatty_flag, tracking, progress
from formula import Formula
from query import Query, Rule, seqToString, _substitute

    
def patch(workingContext, patchFormula):
    """A task of running a set of updates on a knowledge base
    
    This is simpler than an Inference task, in that a patch is only done
    once, patches cannot lead to new patches, etc.
    """
    if diag.chatty_flag >20:
        progress("New Update task, patches from %s applied to %s" %
                (patchFormula, workingContext))
    store = workingContext.store

    true = store.newFormula().close()  #   {}
    universals = Set()
    lhs_done = []
    agenda = {}
    for pred in store.insertion, store.deletion:
        for s in patchFormula.statementsMatching(pred=pred):
            dict = agenda.get(s.subject(), None)
            if dict == None:
                dict = {store.insertion: [], store.deletion: []}
                agenda[s.subject()] = dict
            dict[pred].append(s.object())
    for lhs, dict in sorted(agenda.items()):
        if diag.chatty_flag > 19: progress("Patches lhs= %s: %s" %(lhs, dict))
        if isinstance(lhs, Formula):
            if lhs.universals() != Set():
                raise RuntimeError("""Cannot query for universally quantified things.
                As of 2003/07/28 forAll x ...x cannot be on left hand side of rule.
                This/these were: %s\n""" % lhs.universals())
            
            addenda, minuenda = dict[store.insertion], dict[store.deletion]
            while addenda or minuenda:
                if addenda: conclusion = addenda.pop()
                else: conclusion = true
                if minuenda: retraction = minuenda.pop()
                else: retraction = true

                unmatched = lhs.statements[:]
                templateExistentials = lhs.existentials().copy()
                _substitute({lhs: workingContext}, unmatched)  # Change context column
            
                variablesMentioned = lhs.occurringIn(patchFormula.universals())
                variablesUsed = conclusion.occurringIn(variablesMentioned) | \
                                retraction.occurringIn(variablesMentioned)
                for x in sorted(variablesMentioned):
                    if x not in variablesUsed:
                        templateExistentials.add(x)
                if diag.chatty_flag >20:
                    progress("New Patch  =========== applied to %s" %(workingContext) )
                    for s in lhs.statements: progress("    ", `s`)
                    progress("+=>")
                    for s in conclusion.statements: progress("    ", `s`)
                    progress("-=>")
                    for s in retraction.statements: progress("    ", `s`)
                    progress("Universals declared in outer " + seqToString(patchFormula.universals()))
                    progress(" mentioned in template       " + seqToString(variablesMentioned))
                    progress(" also used in conclusion     " + seqToString(variablesUsed))
                    progress("Existentials in template     " + seqToString(templateExistentials))
    
                q = UpdateQuery(store, 
                        unmatched = unmatched,
                        template = lhs,
                        variables = patchFormula.universals(),
                        existentials =templateExistentials,
                        workingContext = workingContext,
                        conclusion = conclusion,
                        retraction = retraction,
                        rule = None)
                q.resolve()

        
class UpdateQuery(Query):
    "Subclass of query for doing patches onto the KB: adding and removing bits.  Aka KB Update"
    def __init__(self,
               store,
               unmatched,           # List of statements we are trying to match CORRUPTED
               template,                # formula
               variables,           # List of variables to match and return CORRUPTED
               existentials,        # List of variables to match to anything
                                    # Existentials or any kind of variable in subexpression
               workingContext,
               conclusion,      # Things to be added
               retraction,              # Things to be deleted
               rule):               # The rule statement

        Query.__init__(self, store, unmatched=unmatched, template=template, variables=variables,
                existentials= existentials,
                workingContext= workingContext,
                conclusion=conclusion, targetContext = workingContext, rule=rule)
        self.retraction = retraction

    def conclude(self, bindings, evidence = [], extraBNodes=Set(), allBindings=None):
        """When a match found in a query, add conclusions to target formula,
        and also remove retractions.

        Returns the number of statements added."""
        if diag.chatty_flag > 25: progress(
            "Insertions will now be made into %s. Bindings %s" % (self.workingContext, bindings))
        result = Query.conclude(self, bindings, evidence)
        
        # delete statements
        if diag.chatty_flag > 25: progress(
            "Insertions made, deletions will now be made. Bindings %s" % bindings)
        for st in self.retraction:
            s, p, o = st.spo()
            subj = self.doSubst(s, bindings)
            pred = self.doSubst(p, bindings)
            obj = self.doSubst(o, bindings)
            ss = self.workingContext.statementsMatching(
                    subj = subj,  pred = pred, obj = obj)
            if len(ss) != 1:
                progress("""Error: %i matches removing statement {%s %s %s} 
                    bound as {%s %s %s} from %s:\n%s\n""" %
                        (len(ss),s,p,o, subj.uriref(), pred.uriref(), obj.uriref(), self.workingContext, ss
                        ))
                progress(self.workingContext.debugString())
                raise RuntimeError(
                    """Error: %i matches removing statement {%s %s %s} 
                    bound as {%s %s %s} from %s""" %
                        (len(ss),s,p,o, `subj`, pred.uriref(), `obj`, self.workingContext))
            if diag.chatty_flag > 25: progress("Deleting %s" % ss[0])
            self.workingContext.removeStatement(ss[0])
        self.justOne = 1  # drop out of here when done
        return 1     # Success --  behave as a test and drop out

    def doSubst(self, x, bindings):
        if x.generated() and x not in bindings:
            raise ValueError("""Retractions cannot have bnodes in them.
            Use explict variables which also occur on the LHS.
            Found bnode: %s, bindings are: %s""" % (x, bindings))
        return bindings.get(x, x)


             
# ends