Generic Programming in a Dependently Typed Language Generic proofs for generic programs Peter Morris pwm@cs.nott.ac.uk University of Nottingham Generic Programming in a Dependently Typed Language – p. 1/12
This talk • We introduce a more interesting type for equality testing • We return evidence of inequality or inequality • this provides proof that the program is correct • and allows a more sensible flow of control Generic Programming in a Dependently Typed Language – p. 2/12
This talk • We introduce a more interesting type for equality testing • We return evidence of inequality or inequality • this provides proof that the program is correct • and allows a more sensible flow of control • We show how to program with universes for generic programming • we introduce the type of regular types • and the the type of elements for those types • so we can write generic programs Generic Programming in a Dependently Typed Language – p. 2/12
This talk • We introduce a more interesting type for equality testing • We return evidence of inequality or inequality • this provides proof that the program is correct • and allows a more sensible flow of control • We show how to program with universes for generic programming • we introduce the type of regular types • and the the type of elements for those types • so we can write generic programs • We then combine the two ideas Generic Programming in a Dependently Typed Language – p. 2/12
Nat Equality • We are used to equality being defined like this: m, n : Nat let eqN m n : Bool eqN m n ⇐ rec n, case m, case n { eqN zero zero ⇒ true eqN zero (suc n ) ⇒ false eqN (suc m ) zero ⇒ false eqN (suc m ) (suc n ) ⇒ eqN m n } Generic Programming in a Dependently Typed Language – p. 3/12
Nat Equality • We are used to equality being defined like this: m, n : Nat let eqN m n : Bool eqN m n ⇐ rec n, case m, case n { eqN zero zero ⇒ true eqN zero (suc n ) ⇒ false eqN (suc m ) zero ⇒ false eqN (suc m ) (suc n ) ⇒ eqN m n } • But can we do any better with that type? Generic Programming in a Dependently Typed Language – p. 3/12
Nat Equality • ...wouldn’t THIS be better: m, n : Nat let a : A ; b : B eqN m n : ( m = n ) + (( m = n ) → ∅ ) data a = b : ⋆ eqN m n ⇐ rec n, case m, case n T { eqN zero zero ⇒ ??? where refl : a = a eqN zero (suc n ) ⇒ ??? eqN (suc m ) zero ⇒ ??? eqN (suc m ) (suc n ) ⇒ eqN m n ??? } Generic Programming in a Dependently Typed Language – p. 3/12
Nat Equality • ...wouldn’t THIS be better: m, n : Nat let eqN m n : ( m = n ) + (( m = n ) → ∅ ) eqN m n ⇐ rec n, case m, case n { eqN zero zero ⇒ left refl eqN zero (suc n ) ⇒ right ??? eqN (suc m ) zero ⇒ right ??? eqN (suc m ) (suc n ) ⇒ eqN m n ??? } Generic Programming in a Dependently Typed Language – p. 3/12
Nat Equality • ...wouldn’t THIS be better: m, n : Nat let eqN m n : ( m = n ) + (( m = n ) → ∅ ) p : (zero = suc n ) There are no elements eqN m n ⇐ rec n, case m, case n of this type so we don’t { eqN zero zero ⇒ left refl have to define this func- eqN zero (suc n ) ⇒ right ( λp ⇐ case p ) tion! eqN (suc m ) zero ⇒ right ( λq ⇐ case q ) eqN (suc m ) (suc n ) ⇒ eqN m n ??? } Generic Programming in a Dependently Typed Language – p. 3/12
Nat Equality • ...wouldn’t THIS be better: m, n : Nat No! this has the type: let eqN m n : ( m = n ) + (( m = n ) → ∅ ) ( m = n ) + (( m = n ) → ∅ ) we need: eqN m n ⇐ rec n, case m, case n (suc m = suc n )+ { eqN zero zero ⇒ left refl ((suc m = suc n ) → ∅ ) eqN zero (suc n ) ⇒ right ( λp ⇐ case p ) so we have to do a bit eqN (suc m ) zero ⇒ right ( λq ⇐ case q ) more work eqN (suc m ) (suc n ) ⇒ eqN m n ??? } Generic Programming in a Dependently Typed Language – p. 3/12
Nat Equality • ...wouldn’t THIS be better: m, n : Nat let eqN m n : ( m = n ) + (( m = n ) → ∅ ) eqN m n ⇐ rec n, case m, case n { eqN zero zero ⇒ left refl eqN zero (suc n ) ⇒ right ( λp ⇐ case p ) eqN (suc m ) zero ⇒ right ( λq ⇐ case q ) eqN (suc m ) (suc n ) || eqN m n { eqN (suc m ) (suc m ) | left refl ⇒ ??? eqN (suc m ) (suc n ) | right p ⇒ ??? } } Generic Programming in a Dependently Typed Language – p. 3/12
Nat Equality • ...wouldn’t THIS be better: m, n : Nat let eqN m n : ( m = n ) + (( m = n ) → ∅ ) eqN m n ⇐ rec n, case m, case n { eqN zero zero ⇒ left refl eqN zero (suc n ) ⇒ right ( λp ⇐ case p ) eqN (suc m ) zero ⇒ right ( λq ⇐ case q ) eqN (suc m ) (suc n ) || eqN m n { eqN (suc m ) (suc m ) | left refl ⇒ left refl eqN (suc m ) (suc n ) | right p ⇒ right ??? } } Generic Programming in a Dependently Typed Language – p. 3/12
Nat Equality • ...wouldn’t THIS be better: m, n : Nat let eqN m n : ( m = n ) + (( m = n ) → ∅ ) The argument to this eqN m n ⇐ rec n, case m, case n function has type: { eqN zero zero ⇒ left refl suc m = suc n eqN zero (suc n ) ⇒ right ( λp ⇐ case p ) if there is such a proof eqN (suc m ) zero ⇒ right ( λq ⇐ case q ) m and n MUST be the eqN (suc m ) (suc n ) || eqN m n same { eqN (suc m ) (suc m ) | left refl ⇒ left refl eqN (suc m ) (suc n ) | right p ⇒ ( λ refl ⇒ p refl) } } Generic Programming in a Dependently Typed Language – p. 3/12
So what? • why would we want to do it this way? Generic Programming in a Dependently Typed Language – p. 4/12
So what? • why would we want to do it this way? • we don’t just have a program, we have a proof that the program is correct Generic Programming in a Dependently Typed Language – p. 4/12
So what? • why would we want to do it this way? • we don’t just have a program, we have a proof that the program is correct • say we had defined matrix multiplication: x : Matrix l m ; y : Matrix m n let matmult x y : Matrix l n but were given two matrices with dimensions l × m and n × o ? Generic Programming in a Dependently Typed Language – p. 4/12
So what? • why would we want to do it this way? • we don’t just have a program, we have a proof that the program is correct • say we had defined matrix multiplication: x : Matrix l m ; y : Matrix m n let matmult x y : Matrix l n but were given two matrices with dimensions l × m and n × o ? • a proof that (( n = zero) → ∅ ) is exactly what we need to write m ‘div‘ n by structural recursion Generic Programming in a Dependently Typed Language – p. 4/12
So what? • why would we want to do it this way? • we don’t just have a program, we have a proof that the program is correct • say we had defined matrix multiplication: x : Matrix l m ; y : Matrix m n let matmult x y : Matrix l n but were given two matrices with dimensions l × m and n × o ? • a proof that (( n = zero) → ∅ ) is exactly what we need to write m ‘div‘ n by structural recursion • shift your view of programming - obviously correct, elegant programs Generic Programming in a Dependently Typed Language – p. 4/12
Generic Programming • In generic programming we try and define programs that work for a range of data types, to prevent reproduction of code Generic Programming in a Dependently Typed Language – p. 5/12
Generic Programming • In generic programming we try and define programs that work for a range of data types, to prevent reproduction of code • One class of types is the Regular Data types which are defined using: µ, + , × , 1 and 0 Generic Programming in a Dependently Typed Language – p. 5/12
Generic Programming • In generic programming we try and define programs that work for a range of data types, to prevent reproduction of code • One class of types is the Regular Data types which are defined using: µ, + , × , 1 and 0 • For instance: Nat = µX. 1 + X List A = µZ. 1 + ( A × Z ) BTree B = µY.B + ( Y × Y ) Generic Programming in a Dependently Typed Language – p. 5/12
...in Epigram • We can define the Epigram type of Regular Types in n variables (we use debruijn indicies instead of the names above) Generic Programming in a Dependently Typed Language – p. 6/12
...in Epigram • We can define the Epigram type of Regular Types in n variables (we use debruijn indicies instead of the names above) n : Nat T T • data where ; RegType n : ⋆ Zero : RegType n One : RegType n l, r : RegType n x, y : RegType n ; Union l r : RegType n Product x y : RegType n t : RegType (suc n ) T t : RegType (suc n ) ; ; rtz : RegType (suc n ) rts t : RegType n Mu t : RegType n Generic Programming in a Dependently Typed Language – p. 6/12
Elem • We can then define the type of elements of a given closed Regular Type: Generic Programming in a Dependently Typed Language – p. 7/12
Elem • We can then define the type of elements of a given closed Regular Type: rt : RegType zero • data where Elem rt : ⋆ ea : Elem rta ; eb : Elem rtb T ; pair ea eb : Elem (Product rta rtb ) unit : Elem One ea : Elem rta eb : Elem rtb ; inl ea : Elem (Union rta rtb ) inr eb : Elem (Union rta rtb ) e : Elem ′ ( ε, (Mu f )) f in e : Elem (Mu f ) Generic Programming in a Dependently Typed Language – p. 7/12
Recommend
More recommend