Skip to content

What is called "partial order" is in fact merely a preorder. #66

@kindaro

Description

@kindaro

I have a problem with this.

According to some notes, that seem to me correct in this point, a partial order is a preorder that is antisymmetric. What I claim is that it's undecidable whether a preorder relation on an arbitrary datatype is antisymmetric. (Kindly do point out if I am wrong.)

In other words:

quickCheck $ \x y -> (x `leq` y && y `leq` x) && (x == y)

— May fail.

Consider the following example:

module Soup where

import Algebra.PartialOrd
import Test.QuickCheck

data Soup = Juice Bool | Topping | Android deriving (Show, Eq)

instance PartialOrd Soup where
    leq (Juice x) (Juice y) = x <= y
    leq (Juice _) _ = False
    leq _ (Juice _) = False
    leq _ _ = True

instance Arbitrary Soup where
    arbitrary = oneof [Juice <$> arbitrary, return Topping, return Android]

This leq :: Soup -> Soup -> Bool relation on a set of as many as four elements I believe to be reflexive and transitive. Can you see where it fails to be antisymmetric?

What I am suspicious about is that:

  • The naming is misleading in that there are in fact less guarantees than implied.
  • Do these functions even work as expected?

Example, again:

λ partialOrdEq Topping Android 
True

(I thought partial orders were antisymmetric!)

Another example:

cycleMonotone Topping = Android
cycleMonotone Android = Topping
λ lfpFrom Topping cycleMonotone  -- At least it runs in constant space!

(I thought lfpFrom was safe!)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions