-
Notifications
You must be signed in to change notification settings - Fork 87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
What do Lattice
/DistributedLattice
offer?
#18
Comments
Here's an application of lattices: http://www.cs.indiana.edu/~lkuper/papers/lvars-fhpc13.pdf. Perhaps, since the application is parallelism, they're not very helpful as long as the only non-experimental compilation target is JavaScript. However it does look like that will change soon :) Anyway - I agree, I think something is a little off here. Despite the names, we don't currently require that If we require that An example from that paper had the set as the natural numbers augmented with a separate top and bottom, and the relation defined by:
While I believe this relation does fully specify how I wonder if it's sensible to describe If we really want a partial ordering type class, I think it's very unintuitive for |
I always thought Even in the absence of parallelism, using lattices to represent partial information is a good enough use case IMO. You can also interpret boolean algebra in any lattice, which makes it useful for abstract interpretation. |
@hdgarrood most of that makes sense. So since
If you mean the example from Figure 2(a), then shouldn't the last line read instance ordNat :: Ord Nat where
compare _ _ = EQ which would also imply this instance eqNat :: Eq Nat where
(==) _ _ = true and thus the equations above for You still don't see the actual supremum or infimum, so yeah something does seem a bit off, as you stated.
I think |
Wait what? I didn't realize this was how Why not just add one more constructor? data Ordering = LT | EQ | GT | NC where |
Oh - sorry, yeah, I wasn't quite right. I think it's really this: (<=) :: D -> D -> Boolean
_ <= top = true
bottom <= _ = true
x <= y = x == y It's not really expressible in terms of the current In retrospect, I think I confused myself a little by conflating the uniqueness of a However, in PureScript, it's not possible to write a function
Not in Haskell, by the looks of things: https://hackage.haskell.org/package/base-4.8.0.0/docs/Prelude.html#t:Ord I looked back and |
Sorry, I wasn't aware of how I am curious now though. How would you define data D = Bottom | N Nat | Top
instance a :: Eq D where
(==) Bottom Bottom = true
(==) Top Top = true
(==) (N m) (N n) = m == n
(==) _ _ = false
instance b :: Ord D where
compare Top Top = EQ
compare Top _ = GT
compare _ Top = LT
compare Bottom Bottom = EQ
compare Bottom _ = LT
compare _ Bottom = GT
compare _ _ = EQ That seems the only sensible implementation, but then that doesn't satisfy the antisymmetry law. So maybe |
Also, I'm seeing now why it's not so simple to just add another constructor to |
I think the problem is the way (<=) a1 a2 = case a1 `compare` a2 of
GT -> false
_ -> true If we want (<=) a1 a2 = case a1 `compare` a2 of
GT -> false
EQ -> a1 == a2
LT -> true Although I do quite like the idea of a separate constructor for "incomparable".
If |
If it is a total ordering, then there are no interesting lattices, because every ordering is just one big chain. I feel like there is more value in letting Ord represent partial orderings, since Eq lets us disambiguate equal and noncomparable elements. What is the downside of allowing partial orderings? The Map implementation currently works with partial Ord instances, I think.
|
I think total orderings are:
than partial (non-total) orderings, so I think I'd rather have a total ordering type class in the Prelude. For the Map instance, do you mean this one? https://github.com/purescript/purescript-maps/blob/master/src/Data/Map.purs#L50-L51 I guess that means the Ord instance for Map is non-total iff either of its keys or values are, since it's converting to an array of tuples first, and both Array and Tuple use lexicographical ordering. |
Total orderings could easily form a subclass with an additional law. For Map, I was referring to insert and delete which both use the Ord constraint. |
True. What do you think about changing
Come to think of it, I am not sure if a tree-based Map would work without a total ordering on keys. According to http://www.cs.princeton.edu/~dpw/courses/cos326-12/ass/2-3-trees.pdf every element in a right subtree (of either a 2- or 3-node) must be |
I think Map might actually be broken if the keys have a non-total ordering. See https://github.com/hdgarrood/purescript-maps/commit/755a9c874e7b3b879327a6f2d6543d27dcca32b3 |
Also, I'm not sure if a tree-based map implementation like the one in purescript-maps is necessarily broken in the presence of non-total key orderings, but it does appear impossible to ensure logarithmic insert/lookup time in this case. |
I think there's a purpose for both. Maybe the prelude doesn't need to have both. If a partial order is chosen, then I feel Also, there should be more partial orderings than total orderings, since a total ordering is stronger than a partial ordering.
That's what I meant about it breaking trichotomy. It's not necessarily that anyone stated trichotomy holds for |
I'll try to explain what I meant more clearly. Of all the
I don't think I've ever been in a position in Haskell or PureScript where I was aware that I was dealing with a non-totally ordered data type, or found myself in a position where I wanted to abstract over non-total orderings. Generally in Haskell I just slap a I also came across another potential example of brokenness arising from assuming
I think I might have downplayed the severity a little - the test that failed when I tried running the Map tests with partially ordered keys was verifying that |
A not-necessarily-exhaustive list of things that use
I think that non-total orderings should require an explicit opt-in - it's far too easy to forget about them and just write |
Then, I think we have to have We could make The original goal was to refine One downside of having All of the lattice stuff is still in I think the |
Re refining BoolLike, have we considered: class (Eq a, Semiring a) <= BooleanAlgebra a where
not :: a -> a and a few additional laws? We could then have the following functions, with
In psci 0.6.9.5, I have:
so yes, it seems so. |
This seems to have been resolved by purescript/purescript#1099 |
Add code from eff-functions
I was thinking about this the other day. Is anything really gained by either of these two type classes.
I'd posit that there isn't. From the
Ord
superclass, you can derivesup
andinf
:I'm not sure if this is the only law abiding implementation though. But, these two definitions together satisfy all the laws of
Lattice
andDistributedLattice
(alsoBoundedLattice
, but you still need theBounded
superclass). The only thing to be gained is the opportunity to use a slightly more efficient implementation--or in the case of something likeBoolean
, a lazy version. Is that worth it?Maybe it makes sense to drop
Lattice
andDistributedLattice
, providesup
/inf
in terms of theOrd
constraint, keepBoundedLattice
andComplementedLattice
, and move(||)
/(&&)
intoBooleanAlgebra
so you can still provide special implementations.Maybe some other thing makes sense?
The text was updated successfully, but these errors were encountered: