SLIDE 1 A TALE of TWO
by Niki Vazou, Leonidas Lampropoulos and Jeff Polakow
P R O V E R S
SLIDE 2 take ::
Haskell
Int [a] [a]
SLIDE 3 take ::
i:{Int|0≤i} xs:{[a]|i≤len xs} [a]
Liquid
Int
[a]
Haskell
SLIDE 4 take 2 [1,2,3]
OK
take 9 [1,2,3] take ::
i:{Int|0≤i} xs:{[a]|i≤len xs} [a] Int
Liquid Haskell
SLIDE 5 take 2 [1,2,3]
OK
take 9 [1,2,3]
Error
0 ≤ 2 ≤ 3 0 ≤ 9 ≤ 3
SMT
take ::
i:{Int|0≤i} xs:{[a]|i≤len xs} [a] Int
Liquid Haskell
SLIDE 6
Is Liquid Haskell a Theorem Prover?
SLIDE 7
*f is a morphism when
f []=[] ∧ f (x<>y) = f x <> f y
Theorem: Parallelism Equivalence If f is a morphism*between two lists, then f can be applied in parallel. *
Is Liquid Haskell a Theorem Prover?
SLIDE 8
Theorem: Parallelism Equivalence If f is a morphism*between two lists, then .
*f is a morphism when
f []=[] ∧ f (x<>y) = f x <> f y
f x = concat (pmap f (chunk i x))
*
Is Liquid Haskell a Theorem Prover?
SLIDE 9 pEquiv :: f:([a] -> [b])
- > Morphism [a] [b] f
- > x:[a] -> i:Pos
- > {f x = concat (pmap f (chunk i x))}
f x = concat (pmap f (chunk i x))
*f is a morphism when
f []=[] ∧ f (x<>y) = f x <> f y
Is Liquid Haskell a Theorem Prover?
SLIDE 10 pEquiv :: f:([a] -> [b])
- > Morphism [a] [b] f
- > x:[a] -> i:Pos
- > {f x = concat (pmap f (chunk i x))}
f x = concat (pmap f (chunk i x))
*type Morphism a b f = x:a -> y:b ->
f []=[] ∧ f (x<>y) = f x <> f y { }
Is Liquid Haskell a Theorem Prover?
SLIDE 11 pEquiv :: f:([a] -> [b])
- > Morphism [a] [b] f
- > x:[a] -> i:Pos
- > {f x = concat (pmap f (chunk i x))}
f x = concat (pmap f (chunk i x))
Yes!
Theorems: Proofs: Refinement Types (Terminating) Haskell Terms Correctness: Liquid Type Checking
Is Liquid Haskell a Theorem Prover?
SLIDE 12 pEquiv :: f:([a] -> [b])
- > Morphism [a] [b] f
- > x:[a] -> i:Pos
- > {f x = concat (pmap f (chunk i x))}
f x = concat (pmap f (chunk i x))
Demo
Is Liquid Haskell a Theorem Prover?
Yes!
SLIDE 13 Morphism Parallelism Equivalence
Application: String Matching
pEquiv :: RightId [b]
- > f:([a] -> [b])
- > Morphism [a] [b] f
- > x:[a] -> i:Pos
- > {f x = concat (pmap f (chunk i x))}
=> f:([a] -> m)
- > Morphism [a] m f
- > {f x = mconcat (pmap f (chunk i x))}
=> f:(n -> m) (Monoid m) (Chunkable n, Monoid m)
- > Morphism n m f
- > x:n -> i:Pos
SLIDE 14
Find all the occurrences of a target string in an input string.
Application: String Matching
SLIDE 15
“the best of times”
Find all the occurrences of a target string in an input string.
Application: String Matching
SLIDE 16 Find all the occurrences of a target string in an input string.
Application: String Matching
“the best of times”
1 2 3 5 4 6 8 7 9 10 11 13 12 16 15 14 17
Target “es” matches at [6, 16].
SLIDE 17 Verification Time:
200 400 600 800 Exec Spec Proof
669LoC 285LoC 180LoC
Application: String Matching
Human Effort: 5x 20 min 2 months LoC (Proofs/Exec):
SLIDE 18 200 400 600 800 Exec Spec Proof
766LoC 248LoC 122LoC 669LoC 285LoC 180LoC
Verification Time: Human Effort: 5x 20 min 2 months 8x 38 sec 2 weeks
VS.
LoC (Proofs/Exec):
SLIDE 19
VS. Haskell VS. Non-Haskell Proofs
SLIDE 20
VS. SMT- VS. Tactic- Based Automations Haskell VS. Non-Haskell Proofs
SLIDE 21
VS. Intrinsic VS. Extrinsic Verification SMT- VS. Tactic- Based Automations Haskell VS. Non-Haskell Proofs
SLIDE 22 Intrinsic VS. Extrinsic Verification
take :: i:Nat xs:{i≤len xs} {v|len v=i} take 0 _ = [] take i xs = x:take (i-1) xs
SLIDE 23 Definition take := seq.take. Theorem take_spec: ∀i x, i ≤ length x length (take i x) = i. take :: i:Nat xs:{i≤len xs} {v|len v=i} take 0 _ = [] take i xs = x:take (i-1) xs
Intrinsic VS. Extrinsic Verification
SLIDE 24
VS. SMT- VS. Tactic- Based Automations Intrinsic VS. Extrinsic Verification Haskell VS. Non-Haskell Proofs
SLIDE 25
VS. SMT- VS. Tactic- Based Automations Intrinsic VS. Extrinsic Verification Semantic VS. Syntactic Termination Haskell VS. Non-Haskell Proofs
SLIDE 26 chunk :: i:Pos xs:[a] [[a]] / [len xs]
Semantic VS. Syntactic Termination
SLIDE 27 Fixpoint chunk {M: Type} (fuel: nat)
(i: nat) (x: M) : option (list M)
chunk :: i:Pos xs:[a] [[a]] / [len xs]
Semantic VS. Syntactic Termination
SLIDE 28 chunk :: i:Pos xs:[a] [[a]] / [len xs]
SMT
OK / Error
ghc
Big VS. Tiny Trusted Code Base
SLIDE 29
SMT
OK / Error
ghc .hs
Big VS. Tiny Trusted Code Base
SLIDE 30
VS. Big VS. Tiny Trusted Code Base Semantic VS. Syntactic Termination SMT- VS. Tactic- Based Automations Intrinsic VS. Extrinsic Verification Haskell VS. Non-Haskell Proofs
SLIDE 31
VS. Big VS. Tiny Trusted Code Base Semantic VS. Syntactic Termination SMT- VS. Tactic- Based Automations Proof Verifier VS. Assistant Intrinsic VS. Extrinsic Verification Haskell VS. Non-Haskell Proofs
SLIDE 32
A Tale of Two Provers
Conclusion
Liquid Haskell is a promising prover, but needs a lot of Coq-inspired future work.
SLIDE 33
A Tale of Two Provers
Conclusion
Hackage Sharing Proofs Liquid GUI Proof Assistant Fast “tactics”
Thanks!
Liquid Haskell is a promising prover, but needs a lot of Coq-inspired future work.