liquid type inference under the hood
play

Liquid Type Inference under the Hood Micha Reiser Seminar Program - PowerPoint PPT Presentation

Liquid Type Inference under the Hood Micha Reiser Seminar Program Analysis & Transformation University of Applied Sciences Rapperswil 1 Motivation Liquid Type Inference Conclusion 2 Motivation Motivation for Liquid Types Proof


  1. Liquid Type Inference under the Hood Micha Reiser Seminar Program Analysis & Transformation University of Applied Sciences Rapperswil 1

  2. Motivation Liquid Type Inference Conclusion 2

  3. Motivation

  4. Motivation for Liquid Types • Proof fine-granular invariants 3

  5. Motivation for Liquid Types • Proof fine-granular invariants • . . . by using Dependent Types 3

  6. Motivation for Liquid Types • Proof fine-granular invariants • . . . by using Dependent Types • . . . but with Type Inference The more interesting your types get, the less fun it is to write them down [1]. - Benjamin Pierce 3

  7. The List-Average Example avg :: [Int] -> Int avg xs = total `div` n where total = sum xs n = length xs main = do putStrLn "Enter List" list <- readLn putStrLn ("The Avg is: " ++ (show (avg list))) 4

  8. What can possibly go wrong, it is too easy! ./avglist Enter List [1, 5, 10] The Avg is: 5 5

  9. Quite a Lot. . . ./avglist Enter List [] avglist: divide by zero 6

  10. Liquid Haskell Catches these Errors for You avglist.hs:2:10-22: Error: Liquid Type Mismatch 2 | avg xs = total `div` n ^^^^^^^^^^^^^ Inferred type VV : {VV : Int | VV >= 0 && VV == len xs && VV == n} not a subtype of Required type VV : {VV : Int | VV /= 0} In Context xs : {v : [Int] | len v >= 0} n : {n : Int | n >= 0 7

  11. Liquid Type Inference

  12. The Goal . . . is to infer the unknown refinement predicates p of the dependent types T in the program. 8

  13. The Structure of a Dependent Type { ν : B | p } • ν : The special value-variable • B : Base Type like int , bool , char . . . • p : The refinement predicate 9

  14. What is a Liquid Type? A liquid type is a dependent type where the refinement predicate is a conjunction of qualifiers from Q . Q = { 0 ≤ ν, ⋆ ≤ ν, ν < ⋆ } Dependent Types (over 𝐹) Liquid Types (over ℚ ) 10

  15. What is a Liquid Type? A liquid type is a dependent type where the refinement predicate is a conjunction of qualifiers from Q . Q = { 0 ≤ ν, ⋆ ≤ ν, ν < ⋆ } { ν : int | 0 ≤ ν } � Dependent Types (over 𝐹) Liquid Types (over ℚ ) 10

  16. What is a Liquid Type? A liquid type is a dependent type where the refinement predicate is a conjunction of qualifiers from Q . Q = { 0 ≤ ν, ⋆ ≤ ν, ν < ⋆ } { ν : int | 0 ≤ ν } � Dependent Types (over 𝐹) { ν : int | 0 ≤ ν ∧ n ≤ ν } � Liquid Types (over ℚ ) 10

  17. What is a Liquid Type? A liquid type is a dependent type where the refinement predicate is a conjunction of qualifiers from Q . Q = { 0 ≤ ν, ⋆ ≤ ν, ν < ⋆ } { ν : int | 0 ≤ ν } � Dependent Types (over 𝐹) { ν : int | 0 ≤ ν ∧ n ≤ ν } � Liquid Types (over ℚ ) { ν : int | ν = 0 ∧ 0 ≤ ν } ✗ 10

  18. What is a Liquid Type? A liquid type is a dependent type where the refinement predicate is a conjunction of qualifiers from Q . Q = { 0 ≤ ν, ⋆ ≤ ν, ν < ⋆ } { ν : int | 0 ≤ ν } � Dependent Types (over 𝐹) { ν : int | 0 ≤ ν ∧ n ≤ ν } � Liquid Types (over ℚ ) { ν : int | ν = 0 ∧ 0 ≤ ν } ✗ { ν : int | 0 ≤ ν = ⇒ c ≤ ν } ✗ 10

  19. The Approach Do you still remember these: If Alice doubles her age, she would still be 10 years younger than Bob, who was born in 1952. How old are Alice and Bob? [2] 11

  20. The Approach Do you still remember these: If Alice doubles her age, she would still be 10 years younger than Bob, who was born in 1952. How old are Alice and Bob? [2] 1. Create Templates for the Unknown: Alice’s age: a Bob’s age: b 11

  21. The Approach Do you still remember these: If Alice doubles her age, she would still be 10 years younger than Bob, who was born in 1952. How old are Alice and Bob? [2] 1. Create Templates for the Unknown: Alice’s age: a Bob’s age: b 2. Constraints on Templates: 2 a = b − 10 b = 2016 − 1952 11

  22. The Approach Do you still remember these: If Alice doubles her age, she would still be 10 years younger than Bob, who was born in 1952. How old are Alice and Bob? [2] 1. Create Templates for the Unknown: Alice’s age: a Bob’s age: b 2. Constraints on Templates: 2 a = b − 10 b = 2016 − 1952 3. Solve constraints: a = 27 , b = 64 11

  23. Let’s apply this to the sum function In Haskell sum :: Int -> Int sum n = if n < 0 then 0 else n + sum (n - 1) In L1 let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n 12

  24. Step 1: Template Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n 13

  25. Step 1: Template Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n n : int → int ML-Type 13

  26. Step 1: Template Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n n : int → int ML-Type n : { ν : int | ? } → { ν : int | ? } Liquid-Type 13

  27. Step 1: Template Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n n : int → int ML-Type n : { ν : int | ? } → { ν : int | ? } Liquid-Type n : { ν : int | κ n } → { ν : int | κ ret } Template 13

  28. Step 1: Template Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n n : int → int ML-Type n : { ν : int | ? } → { ν : int | ? } Liquid-Type n : { ν : int | κ n } → { ν : int | κ ret } Template Definition A Liquid Type Variable κ is a placeholder for the unknown refinements 13

  29. Two Kind Of Constraints Definition Well-Formedness Constraints define which variables can be used in a refinement predicate. Γ ⊢ T Definition Subtyping Constraints capture proof a subtyping relation between two types (and therefore, the data flow of values). Γ ⊢ T 1 < : T 2 14

  30. Step 2: Well-Formedness Constraint Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n Template sum :: n : { ν : int | κ n } → { ν : int | κ ret } Well-Formedness Constraints: 15

  31. Step 2: Well-Formedness Constraint Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n Template sum :: n : { ν : int | κ n } → { ν : int | κ ret } Well-Formedness Constraints: ∅ ⊢ κ n 15

  32. Step 2: Well-Formedness Constraint Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n Template sum :: n : { ν : int | κ n } → { ν : int | κ ret } Well-Formedness Constraints: ∅ ⊢ κ n n : { ν : int | κ n } ⊢ κ ret 15

  33. Step 2: Subtyping Constraint Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n Template sum :: n : { ν : int | κ n } → { ν : int | κ ret } The then branch flows into the result: 16

  34. Step 2: Subtyping Constraint Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n Template sum :: n : { ν : int | κ n } → { ν : int | κ ret } The then branch flows into the result: sum : . . . , n : { ν : int | κ n } , n < 0 ⊢ { ν : int | ν = 0 } < : { ν : int | κ ret } 16

  35. Step 2: Subtyping Constraint Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1) in s + n Template sum :: n : { ν : int | κ n } → { ν : int | κ ret } The then branch flows into the result: sum : . . . , n : { ν : int | κ n } , n < 0 ⊢ { ν : int | ν = 0 } < : { ν : int | κ ret } n : κ n , n < 0 ⊢ ν = 0 < : κ ret 16

  36. Step 2: Subtyping Constraint Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1 ) in s + n Template sum :: n : { ν : int | κ n } → { ν : int | κ ret } n − 1 flows into the argument of sum : n : κ n , ¬ n < 0 ⊢ ν = n − 1 < : κ n 17

  37. Step 2: Subtyping Constraint Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1 ) in s + n Template sum :: n : { ν : int | κ n } → { ν : int | κ ret } The type of sum ( n − 1) ( s ): { ν : int ⊢ κ ret [ n − 1 / n ] } 18

  38. Step 2: Subtyping Constraint Generation let rec sum = n ⇒ if n < 0 then 0 else let s = sum ( n − 1 ) in s + n Template sum :: n : { ν : int | κ n } → { ν : int | κ ret } The else branch flows into the result n : κ n , s : κ ret [ n − 1 / n ] , ¬ n < 0 ⊢ ν = s + n < : κ ret 19

  39. Step 2: Constraints Well-Formedness ∅ ⊢ κ n n : κ n ⊢ κ ret Subtyping n : κ n , n < 0 ⊢ ν = 0 < : κ ret n : κ n , ¬ n < 0 ⊢ ν = n − 1 < : κ n n : κ n , s : κ ret [ n − 1 / n ] , ¬ n < 0 ⊢ ν = s + n < : κ ret 20

  40. Step 3: Solve Constraints 1. Initial assignment map A ( κ ) with all Qualifiers Q 2. Remove qualifiers that do not satisfy a constraint 21

  41. Step 3: Solve Well-Formedness Constraints Assignment Map A ( κ ) / Current Solution κ n ֌ 0 ≤ ν, ⋆ ≤ ν, ν ≤ ⋆ κ ret ֌ 0 ≤ ν, ⋆ ≤ ν, ν ≤ ⋆ Well-Formedness Constraint ∅ ⊢ κ n n : κ n ⊢ κ ret 22

  42. Step 3: Solve Well-Formedness Constraints Assignment Map A ( κ ) / Current Solution κ n ֌ 0 ≤ ν , ⋆ ≤ ν, ν ≤ ⋆ κ ret ֌ 0 ≤ ν, ⋆ ≤ ν, ν ≤ ⋆ Well-Formedness Constraint ∅ ⊢ κ n SAT 22

Recommend


More recommend