Page 1 of 4 123 ... LastLast
Results 1 to 10 of 33

Thread: Python & the Law of Identity

  1. Top | #1
    Contributor Speakpigeon's Avatar
    Join Date
    Feb 2009
    Location
    Paris, France, EU
    Posts
    6,152
    Archived
    3,662
    Total Posts
    9,814
    Rep Power
    45

    Python & the Law of Identity

    Anyone talks Python?

    Python (programming language)
    Python is an interpreted, high-level, general-purpose programming language. Created by Guido van Rossum and first released in 1991, Python has a design philosophy that emphasizes code readability, notably using significant whitespace. It provides constructs that enable clear programming on both small and large scales. Van Rossum led the language community until stepping down as leader in July 2018.
    Python features a dynamic type system and automatic memory management. It supports multiple programming paradigms, including object-oriented, imperative, functional and procedural, and has a large and comprehensive standard library.
    Python interpreters are available for many operating systems. CPython, the reference implementation of Python, is open source software and has a community-based development model, as do nearly all of Python's other implementations. Python and CPython are managed by the non-profit Python Software Foundation.
    https://en.wikipedia.org/wiki/Python...ming_language)
    Someone posted a link to a bit of code in Python purporting that it falsified the Law of Identity.

    That's here if you're interested: https://repl.it/repls/SuperficialShimmeringAnimatronics.

    The Law of Identity is one of the three laws considered as the foundation of Aristotelian logic. As such, it is crucial to the conventional view of logic whereby illogical is regarded as synonymous with meaningless and nonsensical.

    I'm not here to discuss the Law of Identity, so if someone is interested, please start a thread in the Logic & Epistemology forum.

    Instead, can anyone explain the principle of the algorithm?

    So, here is the code:

    class Aristotelian(object):
    def __init__(self):
    pass
    A = Aristotelian()
    print("Law of Identity: A = A => {}".format(A == A))
    class Human(object):
    def __init__(self):
    pass
    def __eq__(self, other):
    return False
    A = Human()
    print("Law of Humanity: A = A => {}".format(A == A))
    It doesn't seem too complicated, but I'm a complete ignoramus about Python and the guy seems incapable of explaining himself...


    Here is also the blurb to explain the motivation behind the code...
    # The law of identity is the cornerstone of Arostotelian/Classical logic.
    # A = A is True.
    # In the 2nd half of the 20th century the American mathematician Haskell Curry and logician William Alvin Howard discovered an analogy between logical proofs and working computer programs.
    # This is known as the Curry-Howard correspondence.
    # Mathematical proofs are working computer programs.
    # https://en.wikipedia.org/wiki/Curry%...correspondence
    # Therefore, if we can write a working computer program which asserts that A = A is false we have living proof that founding axiom of Aristotelian logic is a mistake.
    # I hereby reject the Aristotelian religion and I embrace Lambda calculus.
    Thanks,
    EB

  2. Top | #2
    Veteran Member
    Join Date
    Dec 2010
    Location
    Riverside City
    Posts
    3,088
    Archived
    6,289
    Total Posts
    9,377
    Rep Power
    35
    The crucial line is
    Code:
    def __eq__(self, other):
        return False
    What this does is just overriding the comparison method with unconditionally returning `false`. It shows that when you don't actually do an identity check but only pretend you did one, you're free to report whatever you choose as the alleged result.

    That's about it.

  3. Top | #3
    Contributor Speakpigeon's Avatar
    Join Date
    Feb 2009
    Location
    Paris, France, EU
    Posts
    6,152
    Archived
    3,662
    Total Posts
    9,814
    Rep Power
    45
    Quote Originally Posted by Jokodo View Post
    The crucial line is
    Code:
    def __eq__(self, other):
        return False
    What this does is just overriding the comparison method with unconditionally returning `false`. It shows that when you don't actually do an identity check but only pretend you did one, you're free to report whatever you choose as the alleged result.

    That's about it.
    Whoa.This is seriously fucked.

    No wonder the guy doesn't want to provide a formal proof equivalent.

    Thanks.
    EB

  4. Top | #4
    Veteran Member
    Join Date
    Dec 2010
    Location
    Riverside City
    Posts
    3,088
    Archived
    6,289
    Total Posts
    9,377
    Rep Power
    35
    Quote Originally Posted by Speakpigeon View Post
    Quote Originally Posted by Jokodo View Post
    The crucial line is
    Code:
    def __eq__(self, other):
        return False
    What this does is just overriding the comparison method with unconditionally returning `false`. It shows that when you don't actually do an identity check but only pretend you did one, you're free to report whatever you choose as the alleged result.

    That's about it.
    Whoa.This is seriously fucked.

    No wonder the guy doesn't want to provide a formal proof equivalent.

    Thanks.
    EB
    To be more precise, '==' and '__eq__' which it is shorthand for isn't actually an identity check but an equality check. It is a very useful feature to be allowed to overwrite it, e. g. if you have your custom data container that contains a lot of information about an entity in the world, and also a timestamp when you last updated the information, it would be very counter-productive if the comparison were to return False because the timestamp differs if your goal is to determine how much info has changed. So you overwrite the equality testing method with something along the lines of "ignore timestamp, check if all other attributes are identical".

    Identity in Python is checked with the keyword is (like the English word) and cannot be overwritten. So if you actually do an identity rather than equality check with the class defined in your code, as below, you get True:
    Code:
    A = Human()
    print("Law of Humanity: A = A => {}".format(A is A))

  5. Top | #5
    Contributor Speakpigeon's Avatar
    Join Date
    Feb 2009
    Location
    Paris, France, EU
    Posts
    6,152
    Archived
    3,662
    Total Posts
    9,814
    Rep Power
    45
    Quote Originally Posted by Jokodo View Post
    To be more precise, '==' and '__eq__' which it is shorthand for isn't actually an identity check but an equality check. It is a very useful feature to be allowed to overwrite it, e. g. if you have your custom data container that contains a lot of information about an entity in the world, and also a timestamp when you last updated the information, it would be very counter-productive if the comparison were to return False because the timestamp differs if your goal is to determine how much info has changed. So you overwrite the equality testing method with something along the lines of "ignore timestamp, check if all other attributes are identical".

    Identity in Python is checked with the keyword is (like the English word) and cannot be overwritten. So if you actually do an identity rather than equality check with the class defined in your code, as below, you get True:
    Code:
    A = Human()
    print("Law of Humanity: A = A => {}".format(A is A))
    That explains another argument this guy has where he produced a kind of "syllogism" where "=" and "is" are mixed up as if meaning the same: Socrates is human v. Socrates = human. He probably got inspired by writing Python code.

    Also, I see how "return False" would be crucial here, but what is the role of "self" and "other" in the line "def __eq__(self, other)"? How does that affects the instruction print("Law of Humanity: A = A => {}".format(A == A))?
    EB

  6. Top | #6
    Veteran Member
    Join Date
    Dec 2010
    Location
    Riverside City
    Posts
    3,088
    Archived
    6,289
    Total Posts
    9,377
    Rep Power
    35
    Quote Originally Posted by Speakpigeon View Post
    Quote Originally Posted by Jokodo View Post
    To be more precise, '==' and '__eq__' which it is shorthand for isn't actually an identity check but an equality check. It is a very useful feature to be allowed to overwrite it, e. g. if you have your custom data container that contains a lot of information about an entity in the world, and also a timestamp when you last updated the information, it would be very counter-productive if the comparison were to return False because the timestamp differs if your goal is to determine how much info has changed. So you overwrite the equality testing method with something along the lines of "ignore timestamp, check if all other attributes are identical".

    Identity in Python is checked with the keyword is (like the English word) and cannot be overwritten. So if you actually do an identity rather than equality check with the class defined in your code, as below, you get True:
    Code:
    A = Human()
    print("Law of Humanity: A = A => {}".format(A is A))
    That explains another argument this guy has where he produced a kind of "syllogism" where "=" and "is" are mixed up as if meaning the same: Socrates is human v. Socrates = human. He probably got inspired by writing Python code.
    Actually, no. Confusing them will lead to non-compiling code in Python as "=" is assignment only, and "==" and "is" have different effects.


    Also, I see how "return False" would be crucial here, but what is the role of "self" and "other" in the line "def __eq__(self, other)"? How does that affects the instruction print("Law of Humanity: A = A => {}".format(A == A))?
    EB
    equality is a two-place predicate, but behind the scenes, everything is an object so operations are really methods on objects. If you write "A == B", what's really happening isn't that some global equality operation grabs both A and B and compares them, but rather (roughly, there's probably some resorting to __cmp__ in between):
    * the interpreter tries if the object A has an `__eq__` method and does whatever that method says;
    * if that fails it checks if B has an `__eq__` method, and
    * if that also fails it does identity checking.

    `self` is the reference to the method's owning object (`this` if you're more familiar with Java), `other` is the reference to whatever it's going to be compared with.

    Here's some silly-but-not-quite-as-silly-as-what-you-quoted code where you might actually overwrite __eq__ in real life, and illustrating what this does:
    Code:
    class Location(object):
        def __init__(self):
            pass
    
    
    earth = Location()
    
    
    class PhysicalObject(object):
        """A physical object with some parameters"""
    
        def __init__(self, mass=0.0, market_value=0.0, composition=None,
                     provenance=None):
            if not provenance or not isinstance(provenance, Location):
                provenance = earth
            self.provenance = provenance
            self.mass = mass  # mass in kg
            self.market_value = market_value  # market value in euros
            self.composition = composition
    
        @classmethod
        def from_object(cls, other):
            return cls(**vars(other))
    
    
    class Commodity(PhysicalObject):
        """A physical object in its role as market commodity"""
    
        def __eq__(self, other):
            try:
                return self.market_value == other.market_value
            except:
                raise ValueError
    
    
    class BalanceWeight(PhysicalObject):
        """A physical object used as a weight for a balance"""
    
        def __eq__(self, other):
            try:
                return self.mass == other.mass
            except Exception as e:
                raise e
    
    
    apple = PhysicalObject(mass=0.2, market_value=0.3)
    nugget = PhysicalObject(mass=0.2, market_value=300)
    nugget2 = PhysicalObject.from_object(
        nugget)  # second object with same specifications
    apple_as_weight = BalanceWeight.from_object(apple)
    nugget_as_valuable = Commodity.from_object(nugget)
    
    print(apple_as_weight == nugget_as_valuable)  # True because
    # BalanceWeight compares only mass
    print(nugget_as_valuable == apple_as_weight)  # False because
    # Commodity compares market value, as it comes first, the nugget's
    # __eq__ method isused
    print(nugget == apple_as_weight)  # True because the plain
    # nugget-as-physical-object doesn't have an __eq__ method, so
    # the apple's is used
    print(nugget == nugget2)  # False because the run-of-the-mill PhysicalObject
    # doesn't have an __eq__ method defined: despite all the same
    # specifications, the two instances are independent objects and the Identity check fails
    Last edited by Jokodo; 02-26-2019 at 07:29 PM.

  7. Top | #7
    Veteran Member
    Join Date
    Dec 2010
    Location
    Riverside City
    Posts
    3,088
    Archived
    6,289
    Total Posts
    9,377
    Rep Power
    35
    Maybe more to the point of your question, self and other are needed in the method definition even though they're not used because otherwise you get a TypeError when you try to pass two arguments to a function that takes none in "A==A".

  8. Top | #8
    Veteran Member
    Join Date
    Jan 2006
    Location
    USA, Mid-Atlantic
    Posts
    2,804
    Archived
    5,710
    Total Posts
    8,514
    Rep Power
    52
    This is dumb, for the reason's pointed out by Jokodo. But more succinctly, without all that rigamarole, he could have just written:

    Code:
    print("A = A => False")

    And it demonstrates the exact same thing, namely, nothing he is claiming. This doesn't prove anything about the Law of Identity. The crux of Curry-Howard is this (taken from wikipedia):

    In other words, the Curry–Howard correspondence is the observation that two families of seemingly unrelated formalisms—namely, the proof systems on one hand, and the models of computation on the other—are in fact the same kind of mathematical objects.

    If one abstracts on the peculiarities of either formalism, the following generalization arises: a proof is a program, and the formula it proves is the type for the program. More informally, this can be seen as an analogy that states that the return type of a function (i.e., the type of values returned by a function) is analogous to a logical theorem, subject to hypotheses corresponding to the types of the argument values passed to the function; and that the program to compute that function is analogous to a proof of that theorem. This sets a form of logic programming on a rigorous foundation: proofs can be represented as programs, and especially as lambda terms, or proofs can be run.
    IOW, the formalisms are equivalent. But because of this, it does not follow that just because I can as easily state an invalid or even unsound proposition using a propositional proof system (no Python required) that I've disproven the Law of Identity.

  9. Top | #9
    Veteran Member
    Join Date
    Jan 2006
    Location
    USA, Mid-Atlantic
    Posts
    2,804
    Archived
    5,710
    Total Posts
    8,514
    Rep Power
    52
    `self` is the reference to the method's owning object (`this` if you're more familiar with Java), `other` is the reference to whatever it's going to be compared with.
    Since this is a programming thread, I'm going to be pedantic.

    In Python, methods *do not belong to instances*. If anything, instances belong to the method.


    Consider this:

    Code:
    >>> class Foo:
    ...    def bar(self):
    ...       return 42
    ...
    >>> foo = Foo()
    >>> foo.bar
    <bound method Foo.bar of <__main__.Foo object at 0x101f0f4e0>>
    >>> foo.bar is foo.bar
    False
    `self` is merely the name we conventionally give to the first argument to a function that will be a method. Methods are simply normal function objects *that belong to a class namespace*, that get *bound* to the instance *when called on the instance*. This is done through the descriptor protocol, because *function objects are descriptors!*, they have a `__get__` method.


    So what is happening on *each method invocation on an instance* is essentially:

    Code:
    >>> Foo.bar
    <function Foo.bar at 0x101ed8950>
    >>> Foo.bar.__get__(foo) # bind the instance to the first argument, this is pretty much what happens underneath the hood
    <bound method Foo.bar of <__main__.Foo object at 0x101f0f4e0>>
    >>> Foo.bar.__get__(foo)()
    42
    >>> foo.bar()
    42
    In the Descriptor HOWTO, we see an example of how this could be implemented in pure Python (of course, in CPython, this is implemented in C):


    Code:
    class Function(object):
        . . .
        def __get__(self, obj, objtype=None):
            "Simulate func_descr_get() in Objects/funcobject.c"
            if obj is None:
                return self
            return types.MethodType(self, obj)

  10. Top | #10
    Contributor Speakpigeon's Avatar
    Join Date
    Feb 2009
    Location
    Paris, France, EU
    Posts
    6,152
    Archived
    3,662
    Total Posts
    9,814
    Rep Power
    45
    Quote Originally Posted by Jokodo View Post
    Maybe more to the point of your question, self and other are needed in the method definition even though they're not used because otherwise you get a TypeError when you try to pass two arguments to a function that takes none in "A==A".
    But I would think "A==A" has two arguments, namely "A" and "A"?

    I thought I had understood that "self" and "other" were the necessary placeholders for whatever will eventually be compared, so that in this particular case, we get both self:= A and other:= A so that the "==" operator gets to compare A with itself. If so, the argument "self" and "other" are used, if only implicitly, and their role is crucial. In particular, this is what is effectively forcing the comparison method to evaluate A==A as False, without in fact any kind of comparison other than A being assigned both to "self" and to "other".

    Could you clarify?
    EB

Similar Threads

  1. Python programming project
    By excreationist in forum Computers and Technology
    Replies: 11
    Last Post: 05-11-2019, 05:37 AM
  2. The Law of Identity: What does it mean?
    By Speakpigeon in forum Metaphysics
    Replies: 20
    Last Post: 04-10-2019, 08:31 AM
  3. Transgender-Identity Infographic
    By lpetrich in forum Social Science
    Replies: 56
    Last Post: 09-05-2018, 01:20 AM
  4. Identity Politics vs Othering
    By Jolly_Penguin in forum Political Discussions
    Replies: 47
    Last Post: 07-09-2018, 10:48 PM
  5. Mistaken Identity? Seriously?
    By RavenSky in forum Political Discussions
    Replies: 7
    Last Post: 08-07-2017, 02:08 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •