-
Notifications
You must be signed in to change notification settings - Fork 5
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
Goal 0.1: insert + parallel map on a set #1
Comments
This should probably just be a branch of LVish with the fancier types. Please branch off of something that is passing unit tests. |
I'm wondering if turning on the LiquidHaskell |
Ok, it's not enough, we still need the total order proof. |
Could you post whatever counterexample convinced you? As far as I can see, in a higher order case like this... I'm not sure how we can state that the totality check was applied to the function passed in. That is, can't I just put the function in another module, check it without |
I too doubt that the totality check can be of any use to a polymorphic function |
I guess the idea was if you guarantee that all call sites for I'm a bit confused about how we would assert totality in a refinement anyway. Wouldn't it be covered by whatever other refinements we have? I.e. any references to the compare operation in the refinements (e.g. antisymmetry/transitivity) mean it has been axiomatized and therefore is total? |
I was confusing the two notions of totality. For example, this is a total function, but it fails the totality requirement of a total order. leqInt :: Int -> Int -> Bool
leqInt x y = False So, instead of (leq : a -> a -> Bool)
-> (x:a -> y:a -> { leq x y || leq y x })
-> (x:a -> y:a -> { leq x y && leq y x => x == y })
-> (x:a -> y:a -> z:a -> { leq x y && leq y z ==> leq x z }) |
I see... does that differ a bit with the |
Oh, but I just realized that writing down that signature you pasted gets very very ugly using |
Here's an ugly and direct expansion to use compare: (cmpr : a -> a -> Ordering)
-> (x:a -> y:a -> z:a -> { cmpr x y == LT && cmpr y z == LT ==> cmpr x z == LT})
-> (x:a -> y:a -> z:a -> { cmpr x y == LT && cmpr y z == EQ ==> cmpr x z == LT})
-> (x:a -> y:a -> z:a -> { cmpr x y == EQ && cmpr y z == LT ==> cmpr x z == LT})
-> (x:a -> y:a -> z:a -> { cmpr x y == EQ && cmpr y z == EQ ==> cmpr x z == EQ})
-> (x:a -> y:a -> { cmpr x y == LT ==> cmpr y x == GT })
-> (x:a -> y:a -> { cmpr x y == EQ ==> cmpr y x == EQ }) |
Well, you can use macros
|
That's a macro at the type level; would it also be possible to just define -- Axiomatize and use as an abbreviation:
leq cmpr x y = cmpr x y == EQ || cmpr x y == LT
insert :: x -> Set x -> (c : a -> a -> Ordering)
-> (x:a -> y:a -> { leq c x y || leq c y x })
-> (x:a -> y:a -> { leq c x y && leq c y x => x == y })
-> (x:a -> y:a -> z:a -> { leq c x y && leq c y z ==> leq c x z })
-> Par _ s () Anyway, I guess it comes down to whatever makes it easiest for the clients to do their proofs. I think we should do a simple |
By the way, just to document it: The thing blocking us from putting these 3 proofs in a product type for convenience is this issue, I believe. @vikraman, have we confirmed that all available product types fail? I.e. a tuple of proofs doesn't work any better than a datatype of proofs? |
It is possible @rrnewton! If you are an inline annotation |
Ah, nice. I wasn't aware of that inline annotation. (FYI, it turns out that I missed some cases, and totality on compare doesn't seem to help anything. Please ignore the compare-based spec above.) Note that @vikraman's current approach actually gets around having a separate argument for each theorem. Instead he can create an abstract datatype for This should support a smooth refactoring path to add the fields as proofs (when we can do refinements inside fields of a product type). That will be necessary for reuse when constructing proofs for compound values like pairs. Actually, we can probably start mocking up a class-based version as well, again, not providing the proofs as methods, but rather a method that returns a VerifiedOrd value. |
Parallel map on a set may not initially seem like it needs total Ord, but in LVish, it does. For instance, if you look at how the traverseSet function works, it must:
The assumption that inserts safely commute requires total
Ord
, as we've been discussing.This goal is met when we have some kind of traverseSet operation that takes a proof of Ord totality (three proofs actually). This should in turn be based on an
insert
function that takes those same proofs.[Note: for this prototype, because of problems with (1) type classes and (2) passing proofs in product types, we will pass proofs as separate function arguments.]
The text was updated successfully, but these errors were encountered: