Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Generic Zero-Cost Reuse for Dependent Types

72003cf388f6f7f95b433de3df9ccd38?s=47 larrytheliquid
September 26, 2018

Generic Zero-Cost Reuse for Dependent Types

Slides for the talk about the corresponding ICFP'18 paper:
https://dl.acm.org/citation.cfm?id=3236799

72003cf388f6f7f95b433de3df9ccd38?s=128

larrytheliquid

September 26, 2018
Tweet

Transcript

  1. Generic Zero-Cost Reuse for Dependent Types Larry Diehl, Denis Firsov,

    and Aaron Stump University of Iowa September 26, 2018 @ ICFP
  2. Problem List append lookup concat assoc

  3. Problem List append Vec lookup concat assoc

  4. ç Problem List append Vec OList lookup concat assoc

  5. Problem List append Vec OList OVec lookup concat assoc

  6. Generic Zero-Cost Reuse This talk is about…

  7. Generic Zero-Cost Reuse This talk is about… appV appL

  8. Generic Zero-Cost Reuse This talk is about… …no runtime penalty

  9. Generic Zero-Cost Reuse This talk is about… …combinators for every

    type
  10. Data Reuse Vec List forget enrich

  11. Data Reuse Vec List forget enrich AppV AppL forget enrich

    Program Reuse
  12. Data Reuse Vec List AppV AppL AssocV AssocL Program Reuse

    Proof Reuse
  13. Data Reuse Vec List AppV AppL AssocL Program Reuse Proof

    Reuse AssocV
  14. Reuse Combinators AppV AppL forget 1 2 3 comb app

    comb app comb app comb app
  15. Outline 1. Manual Reuse (review) 2. Manual Zero-Cost Reuse 3.

    Generic Zero-Cost Reuse (using combinators)
  16. Manual Reuse

  17. data List (A : Set) : Set where nil :

    List A cons : A ! List A ! List A data Vec (A : Set) : ℕ ! Set where nil : Vec A zero cons : {n : ℕ} ! A ! Vec A n ! Vec A (suc n) v2l : {A : Set} {n : ℕ} ! Vec A n ! List A v2l nil = nil v2l (cons x xs) = cons x (v2l xs) appV2appL : AppV ! AppL appV2appL appV xs ys = v2l (appV (l2v xs) (l2v ys))
  18. data List (A : Set) : Set where nil :

    List A cons : A ! List A ! List A data Vec (A : Set) : ℕ ! Set where nil : Vec A zero cons : {n : ℕ} ! A ! Vec A n ! Vec A (suc n) v2l : {A : Set} {n : ℕ} ! Vec A n ! List A v2l nil = nil v2l (cons x xs) = cons x (v2l xs) appV2appL : AppV ! AppL appV2appL appV xs ys = v2l (appV (l2v xs) (l2v ys)) nothing happening?
  19. data List (A : Set) : Set where nil :

    List A cons : A ! List A ! List A data Vec (A : Set) : ℕ ! Set where nil : Vec A zero cons : {n : ℕ} ! A ! Vec A n ! Vec A (suc n) v2l : {A : Set} {n : ℕ} ! Vec A n ! List A v2l nil = nil v2l (cons x xs) = cons x (v2l xs) appV2appL : AppV ! AppL appV2appL appV xs ys = v2l (appV (l2v xs) (l2v ys)) nothing happening?
  20. v2l : {A : Set} {n : ℕ} ! Vec

    A n ! List A v2l nil = nil v2l (cons x xs) = cons x (v2l xs) Nothing Happening? v2lId : {A : Set} {n : ℕ} (xs : Vec A n) ! v2l xs ≡ xs ??? v2l! : {A : Set} {n : ℕ} ! Vec A n ! List A v2l! xs = xs ???
  21. v2l : {A : Set} {n : ℕ} ! Vec

    A n ! List A v2l nil = nil v2l (cons x xs) = cons x (v2l xs) Nothing Happening? v2lId : {A : Set} {n : ℕ} (xs : Vec A n) ! v2l xs ≡ xs ??? v2l! : {A : Set} {n : ℕ} ! Vec A n ! List A v2l! xs = xs ???
  22. v2l : {A : Set} {n : ℕ} ! Vec

    A n ! List A v2l nil = nil v2l (cons x xs) = cons x (v2l xs) Nothing Happening? v2lId : {A : Set} {n : ℕ} (xs : Vec A n) ! v2l xs ≡ xs ??? v2l! : {A : Set} {n : ℕ} ! Vec A n ! List A v2l! xs = xs ???
  23. v2l : {A : Set} {n : ℕ} ! Vec

    A n ! List A v2l nil = nil v2l (cons x xs) = cons x (v2l xs) Something Happening! v2lId : {A : Set} {n : ℕ} (xs : Vec A n) ! v2l xs ≡ xs v2l! : {A : Set} {n : ℕ} ! Vec A n ! List A v2l! xs = xs
  24. data List (A : Set) : Set where nilL :

    List A consL : A ! List A ! List A data Vec (A : Set) : ℕ ! Set where nilV : Vec A zero consV : {n : ℕ} ! A ! Vec A n ! Vec A (suc n) v2l : {A : Set} {n : ℕ} ! Vec A n ! List A v2l nilV = nilL v2l (consV x xs) = consL x (v2l xs) something happening! qualified constructor names
  25. data List (A : Set) : Set where nilL :

    List A consL : A ! List A ! List A data Vec (A : Set) : ℕ ! Set where nilV : Vec A zero consV : {n : ℕ} ! A ! Vec A n ! Vec A (suc n) v2l : {A : Set} {n : ℕ} ! Vec A n ! List A v2l nilV = nilL v2l (consV x xs) = consL x (v2l xs) something happening! qualified constructor names
  26. data List (A : Set) : Set where nilL :

    List A consL : A ! List A ! List A data Vec (A : Set) : ℕ ! Set where nilV : Vec A zero consV : (n : ℕ) ! A ! Vec A n ! Vec A (suc n) v2l : {A : Set} (n : ℕ) ! Vec A n ! List A v2l zero nilV = nilL v2l (suc n)(consV n x xs) = consL x (v2l n xs) something happening! explicit index args
  27. data List (A : Set) : Set where nilL :

    List A consL : A ! List A ! List A data Vec (A : Set) : ℕ ! Set where nilV : Vec A zero consV : (n : ℕ) ! A ! Vec A n ! Vec A (suc n) v2l : {A : Set} (n : ℕ) ! Vec A n ! List A v2l zero nilV = nilL v2l (suc n)(consV n x xs) = consL x (v2l n xs) something happening! explicit index args
  28. …because “something is happening”, reuse is not zero-cost.

  29. Manual Zero-Cost Reuse

  30. Changing Theories Now we will move from Agda’s type theory

    to another type theory (Cedille’s), where our intuition holds (“nothing happening”).
  31. Changing Theories • Primitive Inductive Types • Predicative Quantification •

    Intrinsically Typed Terms • Definitional Equality defined directly over terms • Derived Inductive Types • Impredicative Quantification • Extrinsically Typed Terms • Definitional Equality defined modulo erasing terms to untyped λ-calculus Agda Cedille
  32. Changing Theories • Primitive Inductive Types • Predicative Quantification •

    Intrinsically Typed Terms • Definitional Equality defined directly over terms • Derived Inductive Types • Impredicative Quantification • Extrinsically Typed Terms • Definitional Equality defined modulo erasing terms to untyped λ-calculus Agda Cedille t1 = t2 |t1| =βη |t2| ≜
  33. Cedille Extrinsic Calculus of Constructions + 3 Primitive Types Erased

    Function Space Heterogenous Equality Dependent Intersection
  34. Erased Function Space Erased Function Space Non-Erased Function Space Π

    x : T. T’ ∀ x : T. T’
  35. Erased Function Space Erased Function Space Non-Erased Function Space Π

    x : T. T’ ∀ x : T. T’ syntax
  36. Erased Function Space Erased Function Space Non-Erased Function Space Π

    x : T. T’ ∀ x : T. T’ constraint
  37. Erased Function Space Erased Function Space Non-Erased Function Space Π

    x : T. T’ ∀ x : T. T’ syntax
  38. Erased Function Space Erased Function Space Non-Erased Function Space Π

    x : T. T’ ∀ x : T. T’ domain erased
  39. Erased Function Space Erased Function Space Non-Erased Function Space Π

    x : T. T’ ∀ x : T. T’ erasure by cong.
  40. Erased Function Space Erased Function Space Non-Erased Function Space Π

    x : T. T’ ∀ x : T. T’ abstraction erased
  41. Erased Function Space Erased Function Space Non-Erased Function Space Π

    x : T. T’ ∀ x : T. T’ argument erased
  42. data List (A : Set) : Set where nil :

    List A cons : A ! List A ! List A data Vec (A : Set) : ℕ ! Set where nil : Vec A zero cons : {n : ℕ} ! A ! Vec A n ! Vec A (suc n) Deriving Inductive Types
  43. List : ̣ ➔ ̣ = λ A. ∀ X

    : ̣. X ➔ (A ➔ X ➔ X) ➔ X. Vec : ̣ ➔ ℕ ➔ ̣ = λ A n. ∀ X : ℕ ➔ ̣. X zero ➔ (∀ n : ℕ. A ➔ X n ➔ X (suc n)) ➔ X n. nilL : ∀ A : ̣. List A = Λ A X. λ cN cC. cN. nilV : ∀ A : ̣. Vec A zero = Λ A X. λ cN cC. cN. |nilL| = |nilV| = λ cN cC. cN Church-encoding
  44. nilL : ∀ A : ̣. List A = Λ

    A X. λ cN cC. cN. nilV : ∀ A : ̣. Vec A zero = Λ A X. λ cN cC. cN. |nilL| = |nilV| = λ cN cC. cN Church-encoding Intersection Types for induction principles Mendler-encoding for efficient predecessors Actually… List : ̣ ➔ ̣ = λ A. ∀ X : ̣. X ➔ (A ➔ X ➔ X) ➔ X. Vec : ̣ ➔ ℕ ➔ ̣ = λ A n. ∀ X : ℕ ➔ ̣. X zero ➔ (∀ n : ℕ. A ➔ X n ➔ X (suc n)) ➔ X n.
  45. List : ̣ ➔ ̣ = λ A. ∀ X

    : ̣. X ➔ (A ➔ X ➔ X) ➔ X. Vec : ̣ ➔ ℕ ➔ ̣ = λ A n. ∀ X : ℕ ➔ ̣. X zero ➔ (∀ n : ℕ. A ➔ X n ➔ X (suc n)) ➔ X n. nilL : ∀ A : ̣. List A = Λ A X. λ cN cC. cN. nilV : ∀ A : ̣. Vec A zero = Λ A X. λ cN cC. cN. |nilL| = |nilV| = λ cN cC. cN
  46. List : ̣ ➔ ̣ = λ A. ∀ X

    : ̣. X ➔ (A ➔ X ➔ X) ➔ X. Vec : ̣ ➔ ℕ ➔ ̣ = λ A n. ∀ X : ℕ ➔ ̣. X zero ➔ (∀ n : ℕ. A ➔ X n ➔ X (suc n)) ➔ X n. nilL : ∀ A : ̣. List A = Λ A X. λ cN cC. cN. nilV : ∀ A : ̣. Vec A zero = Λ A X. λ cN cC. cN. A and X erased |nilL| = |nilV| = λ cN cC. cN
  47. List : ̣ ➔ ̣ = λ A. ∀ X

    : ̣. X ➔ (A ➔ X ➔ X) ➔ X. Vec : ̣ ➔ ℕ ➔ ̣ = λ A n. ∀ X : ℕ ➔ ̣. X zero ➔ (∀ n : ℕ. A ➔ X n ➔ X (suc n)) ➔ X n. consL : ∀ A : ̣. A ➔ List A ➔ List A = Λ A. λ x xs. Λ X. λ cN cC. cC x (xs -X cN cC). consV : ∀ A : ̣. ∀ n : ℕ. A ➔ Vec A n ➔ Vec A (suc n) = Λ A n. λ x xs. Λ X. λ cN cC. cC -n x (xs -X cN cC). |consL| = |consV| = λ x xs cN cC. cC x (xs cN cC) application args n and X erased
  48. List : ̣ ➔ ̣ = λ A. ∀ X

    : ̣. X ➔ (A ➔ X ➔ X) ➔ X. Vec : ̣ ➔ ℕ ➔ ̣ = λ A n. ∀ X : ℕ ➔ ̣. X zero ➔ (Π n : ℕ. A ➔ X n ➔ X (suc n)) ➔ X n. consL : ∀ A : ̣. A ➔ List A ➔ List A = Λ A. λ x xs. Λ X. λ cN cC. cC x (xs -X cN cC). consV : ∀ A : ̣. Π n : ℕ. A ➔ Vec A n ➔ Vec A (suc n) = Λ A. λ n. λ x xs. Λ X. λ cN cC. cC n x (xs -X cN cC). NO!!! arg n not erased |consL| ≠ |consV| NO!!!
  49. Heterogenous Equality Heterogenous Equality t1 ≃ t2 nilL : List

    A nilV : Vec A zero |nilL| = |nilV| β : nilL ≃ nilV
  50. Heterogenous Equality Heterogenous Equality t1 ≃ t2 nilL : List

    A nilV : Vec A zero |nilL| = |nilV| β : nilL ≃ nilV
  51. Heterogenous Equality Heterogenous Equality t1 ≃ t2

  52. Heterogenous Equality Heterogenous Equality t1 ≃ t2

  53. Heterogenous Equality Heterogenous Equality t1 ≃ t2

  54. Heterogenous Equality Heterogenous Equality t1 ≃ t2

  55. Heterogenous Equality Heterogenous Equality t1 ≃ t2

  56. Heterogenous Equality Heterogenous Equality t1 ≃ t2

  57. v2l : {A : Set} {n : ℕ} ! Vec

    A n ! List A v2l nil = nil v2l (cons x xs) = cons x (v2l xs) Nothing Happening? v2lId : {A : Set} {n : ℕ} (xs : Vec A n) ! v2l xs ≡ xs ??? v2l! : {A : Set} {n : ℕ} ! Vec A n ! List A v2l! xs = xs ???
  58. v2l : ∀ A : ̣. ∀ n : Nat.

    Vec A n ➔ List A = elimVec nilL (λ x ih. consL x ih). Nothing Happening! v2lId : ∀ A : ̣. ∀ n : Nat. Π xs : Vec A n. v2l xs ≃ xs = elimVec β (λ x ih. ρ ih - β). v2l! : ∀ A : ̣. ∀ n : Nat. Vec A n ➔ List A = Λ A n. λ xs. φ (v2lId xs) - (v2l xs) {xs}. extrinsic het. eq.
  59. v2l : ∀ A : ̣. ∀ n : Nat.

    Vec A n ➔ List A = elimVec nilL (λ x ih. consL x ih). Nothing Happening! v2lId : ∀ A : ̣. ∀ n : Nat. Π xs : Vec A n. v2l xs ≃ xs = elimVec β (λ x ih. ρ ih - β). v2l! : ∀ A : ̣. ∀ n : Nat. Vec A n ➔ List A = Λ A n. λ xs. φ (v2lId xs) - (v2l xs) {xs}. |v2l!| = λ xs. xs
  60. Generic Zero-Cost Reuse (using combinators)

  61. Type of Identity Functions A type abstraction that represents the

    existence of an identity function from A to B (after erasure).
  62. Type of Identity Functions There are many ways to extrinsically

    type the identity function (e.g. v2l!, l2v!, appV2appL!, etc.). The type abstraction Id A B represents the existence of an identity function (after erasure) from A to B. Id A B = Π a : A. Σ b : B. b ≃ a. elimId f : A ➔ B |elimId f| = λ x. x f : Id A B extrinsic het. eq.
  63. Type of Identity Functions There are many ways to extrinsically

    type the identity function (e.g. v2l!, l2v!, appV2appL!, etc.). The type abstraction Id A B represents the existence of an identity function (after erasure) from A to B. Id A B = Π a : A. Σ b : B. b ≃ a. elimId f : A ➔ B |elimId f| = λ x. x f : Id A B
  64. Type of Identity Functions There are many ways to extrinsically

    type the identity function (e.g. v2l!, l2v!, appV2appL!, etc.). The type abstraction Id A B represents the existence of an identity function (after erasure) from A to B. Id A B = Π a : A. Σ b : B. b ≃ a. elimId f : A ➔ B |elimId f| = λ x. x f : Id A B
  65. Type of Identity Functions There are many ways to extrinsically

    type the identity function (e.g. v2l!, l2v!, appV2appL!, etc.). The type abstraction Id A B represents the existence of an identity function (after erasure) from A to B. Id A B = Π a : A. Σ b : B. b ≃ a. elimId f : A ➔ B |elimId f| = λ x. x f : Id A B
  66. Id-Closed Combinators Program (Function Type) Reuse Id (∀ i :

    I. X i ➔ X' i) (Y ➔ Y') Data (Fixpoint Type) Reuse ∀ i : I. Id (IFix I F imapF i) (Fix G imapG)
  67. Id-Closed Combinators Program (Function Type) Reuse Id (∀ i :

    I. X i ➔ X' i) (Y ➔ Y') Data (Fixpoint Type) Reuse ∀ i : I. Id (IFix I F imapF i) (Fix G imapG)
  68. Id-Closed Combinators Program (Function Type) Reuse Id (∀ i :

    I. X i ➔ X' i) (Y ➔ Y') Data (Fixpoint Type) Reuse ∀ i : I. Id (IFix I F imapF i) (Fix G imapG)
  69. Id-Closed Combinators Program (Function Type) Reuse Id (∀ i :

    I. X i ➔ X' i) (Y ➔ Y') Data (Fixpoint Type) Reuse ∀ i : I. Id (IFix I F imapF i) (Fix G imapG) Id-closed combinators allow for data and functions to be reused incrementally, and typing ensures the results of reuse will be zero- cost (i.e., erase to the identity function). Program (Function Type) Reuse Id (∀ i : I. X i ➔ X' i) (Y ➔ Y')
  70. Id-Closed Combinators Program (Function Type) Reuse Id (∀ i :

    I. X i ➔ X' i) (Y ➔ Y') Data (Fixpoint Type) Reuse ∀ i : I. Id (IFix I F imapF i) (Fix G imapG) Id-closed combinators allow for data and functions to be reused incrementally, and typing ensures the results of reuse will be zero- cost (i.e., erase to the identity function). Program (Function Type) Reuse Id (∀ i : I. X i ➔ X' i) (Y ➔ Y') left-component ( ) erased
  71. AppV AppL forget 1 2 3 AppV : ̣ =

    ∀ A : ̣. ∀ n : Nat. Vec A n ➔ ∀ m : Nat. Vec A m ➔ Vec A (add n m). AppL : ̣ = ∀ A : ̣. List A ➔ List A ➔ List A.
  72. AppV AppL forget 1 2 3 AppV : ̣ =

    ∀ A : ̣. ∀ n : Nat. Vec A n ➔ ∀ m : Nat. Vec A m ➔ Vec A (add n m). AppL : ̣ = ∀ A : ̣. List A ➔ List A ➔ List A. // Id (∀ A : ̣. •) (∀ A : ̣. •) copyType (Λ A. // Id (∀ n : Nat. Vec A n ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (∀ m : Nat. Vec A m ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (Vec A (add (len xs) (len ys))) (List A) v2l)))
  73. AppV AppL forget 1 2 3 AppV : ̣ =

    ∀ A : ̣. ∀ n : Nat. Vec A n ➔ ∀ m : Nat. Vec A m ➔ Vec A (add n m). AppL : ̣ = ∀ A : ̣. List A ➔ List A ➔ List A. // Id (∀ A : ̣. •) (∀ A : ̣. •) copyType (Λ A. // Id (∀ n : Nat. Vec A n ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (∀ m : Nat. Vec A m ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (Vec A (add (len xs) (len ys))) (List A) v2l)))
  74. AppV AppL forget 1 2 3 AppV : ̣ =

    ∀ A : ̣. ∀ n : Nat. Vec A n ➔ ∀ m : Nat. Vec A m ➔ Vec A (add n m). AppL : ̣ = ∀ A : ̣. List A ➔ List A ➔ List A. // Id (∀ A : ̣. •) (∀ A : ̣. •) copyType (Λ A. // Id (∀ n : Nat. Vec A n ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (∀ m : Nat. Vec A m ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (Vec A (add (len xs) (len ys))) (List A) v2l)))
  75. AppV AppL forget 1 2 3 AppV : ̣ =

    ∀ A : ̣. ∀ n : Nat. Vec A n ➔ ∀ m : Nat. Vec A m ➔ Vec A (add n m). AppL : ̣ = ∀ A : ̣. List A ➔ List A ➔ List A. // Id (∀ A : ̣. •) (∀ A : ̣. •) copyType (Λ A. // Id (∀ n : Nat. Vec A n ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (∀ m : Nat. Vec A m ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (Vec A (add (len xs) (len ys))) (List A) v2l)))
  76. AppV AppL forget 1 2 3 AppV : ̣ =

    ∀ A : ̣. ∀ n : Nat. Vec A n ➔ ∀ m : Nat. Vec A m ➔ Vec A (add n m). AppL : ̣ = ∀ A : ̣. List A ➔ List A ➔ List A. // Id (∀ A : ̣. •) (∀ A : ̣. •) copyType (Λ A. // Id (∀ n : Nat. Vec A n ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (∀ m : Nat. Vec A m ➔ •) (List A ➔ •) allArr2arr len l2v (λ xs. // Id (Vec A (add (len xs) (len ys))) (List A) v2l)))
  77. We hope that is a step in the right direction

    for making dependently typed languages more usable, via code reuse without runtime penalty. Conclusion Tutorial tomorrow on dependently typed programming in Cedille! … wrapping up my postdoc at University of Iowa, please talk to me about any positions :)
  78. We hope that is a step in the right direction

    for making dependently typed languages more usable, via code reuse without runtime penalty. Conclusion Tutorial tomorrow on dependently typed programming in Cedille! … wrapping up my postdoc at University of Iowa, please talk to me about any positions :)
  79. We hope that is a step in the right direction

    for making dependently typed languages more usable, via code reuse without runtime penalty. Conclusion Tutorial tomorrow on dependently typed programming in Cedille! … wrapping up my postdoc at University of Iowa, please talk to me about any positions :)
  80. • Details on combinators • Background on fixpoint types in

    Cedille • Enriching direction of reuse • Case study: Reuse between untyped and intrinsically typed STLC terms • Comparisons to related work like ornaments and dependent interoperability In The Paper
  81. None
  82. AppV AppL forget 1 2 3 AppV : ̣ =

    ∀ A : ̣. ∀ n : Nat. Vec A n ➔ ∀ m : Nat. Vec A m ➔ Vec A (add n m). AppL : ̣ = ∀ A : ̣. List A ➔ List A ➔ List A. any f : AppV works!
  83. data List (A : Set) : Set where nil :

    List A cons : A ! List A ! List A data Vec (A : Set) : ℕ ! Set where nil : Vec A zero cons : {n : ℕ} ! A ! Vec A n ! Vec A (suc n) v2l : {A : Set} {n : ℕ} ! Vec A n ! List A v2l nil = nil v2l (cons x xs) = cons x (v2l xs) appV2appL : AppV ! AppL appV2appL appV xs ys = v2l (appV (l2v xs) (l2v ys)) nothing happening?
  84. appV2appL : AppV ➔ AppL = λ appV xs ys.

    v2l (appV (l2v xs) (l2v ys)). Nothing Happening! appV2appLId : Π f : AppV. ∀ A : ̣. Π xs ys : List A. appV2appL f xs ys ≃ f (l2v! xs) (l2v! ys) = λ f xs ys. ρ (l2vId xs) - ρ (l2vId ys) - ρ (v2lId (f xs ys)) - β rewrites
  85. Nothing Happening! appV2appL! : AppV ➔ AppL = λ f

    xs ys. φ (appV2appLId f xs ys) - (appV2appL f xs ys) {f (l2v! xs) (l2v! ys)}. |l2v!| = λ xs. xs |appV2appL!| = λ f xs ys. f xs ys = λ f. f