liquidhaskell-0.8.0.2: docs/slides/BOS14/README.md
Todo
----
+ CREATE 00_Motivation_Bugs.lhs **TUFTS**
+ sequence, BUGs, 1984, etc.
+ UPDATE 11_Evaluation.lhs **TUFTS,BOS**
+ Add bits about "comments" ---> "types"
+ Nicer GRAPHS
+ CREATE HARDWIRED-RED-BLACK-BST.lhs **TUFTS**
+ INV 1: COLOR
+ INV 2: HEIGHT
+ INV 3: ORDER
+ CREATE 03_Memory.lhs **TUFTS, BOS**
+ and associated demo file, from eseidel's BS demo.
+ UPDATE 09_Laziness.lhs **BOS**
+ Use math fonts
+ CHECK 10_Termination.lhs **BOS**
+ link to Termination.hs demo
Comparison with DT
------------------
-- Grisly HS+DT proof
https://github.com/jstolarek/dep-typed-wbl-heaps-hs/blob/master/src/TwoPassMerge/CombinedProofs.hs#L68
-- HS (no proof)
https://github.com/jstolarek/dep-typed-wbl-heaps-hs/blob/master/src/TwoPassMerge/NoProofs.hs#L96
-- HS+LH proof
https://github.com/ucsd-progsys/liquidhaskell/blob/master/tests/pos/WBL.hs#L129
BOS-Haskell Plan
----------------
[35] PART I "refinement types"
* [5] 00_Motivation: "Go Wrong"
* [15] 01_SimpleRefinements (upto VC, Abs) but no Kvar
+ Demo : hs/000_Refinements.hs
+ Demo : hs/001_Refinements.hs
* [15] 02_Measures
+ Demo : hs/01_Elements.hs
[20] PART II "case studies"
* [5] lhs/02_RedBlack.lhs
* [15] lhs/13_Memory.lhs
[25] PART III "haskell"
* [10] lhs/09_Laziness.lhs
* [10] lhs/10_Termination.lhs
* [3] lhs/11_Evaluation.lhs
* [2] lhs/12_Conclusion.lhs
[20] PART IV "abstract refinements"
* [5] 04_Abstract Refinements.lhs
+ Demo : 02_AbstractRefinements.hs (listMax)
* [7] Demo Inductive
+ Demo: 02_AbstractRefinements.hs (ifoldr, append, filter)
* [8] Demo Recursive
+ Demo: 02_AbstractRefinements.hs (insertSort, ifoldr-insertSort)
+ Demo: 04_Streams.hs (repeat, take)
? [10] Demo Indexed
+ Demo: KMP.hs
Tufts Plan
----------
* [7] 00_Motivation_Long
+ Bugs
+ Well typed Program Go Wrong
* [10] 01_SimpleRefinements
+ upto VC, Abs
* [10] 02_Measures
+ Demo : 00_Refinements.hs
+ Demo : 01_Elements.hs
* [5] 02_RedBlack
+ Complex : RED-BLACK Trees
* [5] 03_Memory_short?
+ Upto just the low-level API?
* [5] 11_Evaluation.lhs
+ Add bits about "comments" ---> "types"
* [2] 12_Conclusion.lhs
Brown Plan
----------
* [5] 00_Motivation: "Go Wrong"
* [5] 01_SimpleRefinements (upto VC, Abs, but no Kvar)
* [10] 02_Measures [TODO: cut RED-BLACK]
+ Demo : 00_Refinements.hs
+ Demo : 01_Elements.hs
* [5] 04_Abstract Refinements
+ Demo : 02_AbstractRefinements.hs (listMax)
* [5] 06_Inductive
+ Describe: [TODO: CUT ?foldn] foldr
+ Demo: 02_AbstractRefinements.hs (foldr, append, filter)
* [5] 08_Recursive
+ Describe: list-ord
+ Demo: 02_AbstractRefinements.hs (insertSort, ifoldr-insertSort)
+ Show: GhcListSort.hs
+ Describe: tree-ord
+ Demo: Stream
* [3] 11_Evaluation.lhs
* [2] 12_Conclusion.lhs
Harvard Plan
------------
* [5] 00_Motivation: "Go Wrong"
* [5] 01_SimpleRefinements (upto VC, Abs, but no Kvar)
* [10] 02_Measures [TODO: cut RED-BLACK]
+ Demo : 00_Refinements.hs (upto "wtAverage")
+ Demo : 01_Elements.hs
* [5] 04_Abstract Refinements
+ Demo : 02_AbstractRefinements.hs (listMax)
* [5] 06_Inductive
+ Describe: [TODO: CUT ?foldn] foldr
+ Demo: 02_AbstractRefinements.hs (foldr, append, filter)
* [5] 08_Recursive
+ Describe: list-ord
+ Demo: 02_AbstractRefinements.hs (insertSort, ifoldr-insertSort)
+ Show: GhcListSort.hs
+ Describe: tree-ord
+ [TODO: CUT] Demo: RBTree-Ord
+ Demo: Stream
* [TODO: CUT] [5] 07_Array
[TODO: CUT] + Describe: Array
[TODO: CUT] + Demo: KMP
* [3] 11_Evaluation.lhs
* [2] 12_Conclusion.lhs
Bytestring Details
------------------
-- | A variety of 'head' for non-empty ByteStrings. 'unsafeHead' omits
-- the check for the empty case, which is good for performance, but
-- there is an obligation on the programmer to provide a proof that the
-- ByteString is non-empty.
{-@ unsafeHead :: ByteStringNE -> Char @-}
unsafeHead :: ByteString -> Char
unsafeHead = w2c . B.unsafeHead
{-# INLINE unsafeHead #-}
type ByteStringNE = {v:ByteString | 0 < bLength v}
-- | Unsafe 'ByteString' index (subscript) operator, starting from 0, returning a 'Word8'
-- This omits the bounds check, which means there is an accompanying
-- obligation on the programmer to ensure the bounds are checked in some
-- other way.
{-@ type OkIdx B = {v:Nat | v < bLength B} @-}
{-@ unsafeIndex :: b:ByteString -> OkIdx b -> Word8 @-}
unsafeIndex :: ByteString -> Int -> Word8
unsafeIndex (PS x s l) i = assert (i >= 0 && i < l) $
inlinePerformIO $ withForeignPtr x $ \p -> peekByteOff p (s+i)
Low-Level Memory
----------------
1. "Haskell HeartBleed" (using BS)
2. Memory API (calls out to C)
+ mallocForeignPtrBytes
+ withForeignPtr
+ peek
+ poke
+ plusPtr
First with types, then with Refined Types.
3. Examples
+ okPtr
+ badPtr (replace 3 with 6)
4. `ByteString`
+ invariant
+ goodBS1, goodBS2
+ badBS1, badBS2
5. `create`
+ good call
+ bad call
6. `pack`
7. `unpack`
8. `unsafeTake`
9. `heartBleed` redux.
`peekByteOff p i == peek (p `plusPtr` i)`
\begin{code}
module BSCrash where
import Data.ByteString.Char8 as C
import Data.ByteString as B
import Data.ByteString.Unsafe as U
heartBleed s n = s'
where
b = C.pack s -- "Ranjit"
b' = U.unsafeTake n b -- 20
s' = C.unpack b'
-- > let ex = "Ranjit Loves Burritos"
-- > heartBleed ex 1
-- "R"
-- > heartBleed ex 6
-- > "Ranjit"
-- > heartBleed ex 10
-- > "Ranjit Lov"
-- > heartBleed ex 30
-- > "Ranjit Loves Burritos\NUL\NUL\NUL\201\&1j\DC3\SOH\NUL"
\end{code}