This file is indexed.

/usr/lib/python2.7/dist-packages/ufl/exprequals.py is in python-ufl 1.4.0-1.

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
from ufl.log import error
from ufl.operatorbase import Operator
from ufl.terminal import Terminal
from ufl.common import fast_pre_traversal

def _expr_equals0(a, b):
    # Cutoff for different type
    if type(a) != type(b):
        return False

    # Cutoff for same object
    if a is b:
        return True

    # Iterate over pairs of potentially matching subexpressions
    input = [(a, b)]
    while input:
        a, b = input.pop()

        # Cutoff for different type
        if type(a) != type(b):
            return False

        # Get operands
        aops = a.operands()
        bops = b.operands()
        if aops:
            if len(aops) != len(bops):
                return False
            # Add children for checking
            input.extend(izip(aops, bops))
        else:
            # Compare terminals
            if not a == b:
                return False

    # Everything checked out fine, expressions must be equal
    return True

def _expr_equals1(a, b):
    # Cutoff for different type
    if type(a) != type(b):
        return False
    # Cutoff for same object
    if a is b:
        return True
    # Compare entire expression structure
    for x,y in izip(fast_pre_traversal(a), fast_pre_traversal(b)):
        if type(x) != type(y):
            return False
        #if isinstance(Terminal, x) and not x == y:
        if x.operands() == () and not x == y:
            return False
    # Equal terminals and types, a and b must be equal
    return True

def _expr_equals2(a, b):
    # Cutoff for different type
    if type(a) != type(b):
        return False
    # Cutoff for same object
    if a is b:
        return True
    from ufl.algorithms.traversal import traverse_terminals, traverse_operands
    # Check for equal terminals
    for x,y in izip(traverse_terminals(a), traverse_terminals(b)):
        if x != y:
            return False
    # Check for matching operator types
    for x,y in izip(traverse_operands(a), traverse_operands(b)):
        if type(x) != type(y):
            return False
    # Equal terminals and operands, a and b must be equal
    return True

equalsrecursed = {}
equalscalls = {}
collisions = {}
def print_collisions():
    print
    print "Collision statistics:"
    keys = sorted(equalscalls.keys(), key=lambda x: collisions.get(x,0))
    for k in keys:
        co = collisions.get(k,0)
        ca = equalscalls[k]
        print k, co, ca, int(100.0*co/ca)
    print "Recursion statistics:"
    keys = sorted(keys, key=lambda x: equalsrecursed.get(x,0))
    for k in keys:
        r = equalsrecursed.get(k,0)
        ca = equalscalls[k]
        print k, r, ca, int(100.0*r/ca)
    print

def _expr_equals3(self, other): # Much faster than the more complex algorithms above!
    """Checks whether the two expressions are represented the
    exact same way. This does not check if the expressions are
    mathematically equal or equivalent! Used by sets and dicts."""

    # Code for counting number of equals calls:
    #equalscalls[type(self)] = equalscalls.get(type(self),0) + 1

    # Fast cutoff for common case
    if type(self) != type(other):
        return False

    # TODO: Test how this affects the run time:
    # Compare hashes if hash is cached
    # (NB! never access _hash directly, it may be computed on demand in __hash__)
    if (hasattr(self, "_hash") and hash(self) != hash(other)):
        return False

    # Large objects are costly to compare with themselves
    if self is other:
        return True

    if isinstance(self, Operator):
        # Just let python handle the recursion
        #equal = self.operands() == other.operands()
        # Recurse manually to call _expr_equals3 directly without the class EQ overhead!
        equal = all(_expr_equals3(a, b) for (a,b) in zip(self.operands(), other.operands()))
    else:
        # Compare terminal representations to include all terminal data
        #equal = repr(self) == repr(other)
        # Compare terminals with custom == to capture subclass overloading of __eq__
        equal = self == other

    # At this point, self and other has the same hash, and equal _should_ be True...
    # Code for measuring amount of collisions:
    #if not equal:
    #    collisions[type(self)] = collisions.get(type(self), 0) + 1

    # Code for counting number of recursive calls:
    #equalsrecursed[type(self)] = equalsrecursed.get(type(self),0) + 1

    # Debugging check: (has been enabled for a long while without any fails as of nov. 30th 2012
    #req = repr(self) == repr(other)
    #if req != equal: # This may legally fail for test/trial functions from PyDOLFIN
    #    print '\n'*3
    #    print self
    #    print other
    #    print '\n'*3
    #    error("INVALID COMPARISON!")

    return equal

expr_equals = _expr_equals3