type-preserving compilation via dependently typed syntax in agdaabela/talktypes2020.pdf ·...

25
Type-preserving compilation via dependently typed syntax in Agda Andreas Abel 1 1 Department of Computer Science and Engineering Chalmers and Gothenburg University, Sweden Types for Proofs and Programs (TYPES 2020) Torino, Italy Scheduled for 2-5 March (Cancelled due to COVID-19) Abel Dependently-Typed Compilation TYPES 2020 1 / 25

Upload: others

Post on 27-Jul-2020

14 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Type-preserving compilationvia dependently typed syntax in Agda

Andreas Abel1

1Department of Computer Science and EngineeringChalmers and Gothenburg University, Sweden

Types for Proofs and Programs (TYPES 2020)Torino, Italy

Scheduled for 2-5 March(Cancelled due to COVID-19)

Abel Dependently-Typed Compilation TYPES 2020 1 / 25

Page 2: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Introduction

Verified Compilation

Tony Hoare’s Grand Challenge: Verified compilation.

CompCert for the masses?

Full verification may be too expensive (> 90% of impl. effort).

Sweet spot: lots of confidence for little verification.

Compiler be a total function.

Abel Dependently-Typed Compilation TYPES 2020 2 / 25

Page 3: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Introduction

Verifying Type-Safety

Robin Milner: Well-typed programs do not go wrong.

Types checked by compiler front-end.

Goal: preserve properties through back-end.

Type safety.“Execution safety”: No illegal jumps.

Typed machine language (e.g. LLVM).

Abel Dependently-Typed Compilation TYPES 2020 3 / 25

Page 4: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Introduction

Method

Implement compiler in a dependently-typed programming language.

Represent well-typed syntax as indexed data types.

Type-correct compilation enforced by indexing discipline.

Abel Dependently-Typed Compilation TYPES 2020 4 / 25

Page 5: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Introduction

Intrinsically well-typed syntax

object language meta languageuntyped simply typed

e. g.: syntax trees e. g.: (C, Java), Scala, ML, Haskell, . . .

simply typed dependently typede. g.: λ-calculus, C-- e. g.: Agda, Coq, Idris, Lean, . . .

dependently typed dependently typed

Abel Dependently-Typed Compilation TYPES 2020 5 / 25

Page 6: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Compiler for C--

Pipeline

C-- text

parser��

abstract syntax

type checker��

well-typed syntax

code generator

��well-formed machine code

printer��

JVM-- symbolic assembler

Abel Dependently-Typed Compilation TYPES 2020 6 / 25

Page 7: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Compiler for C--

C-- by example

// Does p divide q?

bool divides (int p, int q) {

return (q / p) * p == q;

}

// Is p prime?

bool prime (int p) {

if (p <= 2) return p == 2;

else {

int q = 3;

while (q * q <= p)

if (divides(q,p)) return false;

else q = q + 2;

}

return true;

}

Abel Dependently-Typed Compilation TYPES 2020 7 / 25

Page 8: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Compiler for C--

C-- language elements

Hierarchical:

function definitions contain statements,statements contain expressions.

Types: Ty = {int, double, bool, void}.Variables (function parameters, local variables) are scoped.

Some statements declare new variables (int q = 3;).

Control structures: if, while, return.

Abel Dependently-Typed Compilation TYPES 2020 8 / 25

Page 9: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-typed syntax

Typing contexts

Scoping is managed by typing contexts Γ, snoc-lists of types.

Example list int2 = [int, int]:

ε.int.int

Category Cxt:Objects: typing contexts Γ.Morphisms Γ ⊆ ∆ are ways in which Γ is a sublist of ∆.

skipas ⊆ bs

as ⊆ (bs.b)keep

as ⊆ bs

(as.a) ⊆ (bs.a)done

ε ⊆ ε

Variables (de Bruijn indexes) pick a type from a context.

Vart Γ ∼= ([t] ⊆ Γ)

Quiz:1 How many morphisms in int2 ⊆ int5?2 How many morphisms in intk ⊆ intn?

Abel Dependently-Typed Compilation TYPES 2020 9 / 25

Page 10: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-typed syntax

Cxt has only weak push-outs

[] //

��

[a]

��

��

[b] //

**

[a, b]

[b, a]

Abel Dependently-Typed Compilation TYPES 2020 10 / 25

Page 11: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-typed syntax

Well-typed syntax

Vart Γ variables of type t

Expt Γ expressions of type t

Stmr Γ Γ′ statements

r : return type of functionΓ: context before statementΓ′ = Γ.∆: context after

Stmsr Γ Γ′ statement sequences: free category over Stm.

Abel Dependently-Typed Compilation TYPES 2020 11 / 25

Page 12: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-typed syntax

Expressions

Expt : Cxt→ Set functor

maps hom η : Γ ⊆ ∆ to weakening [η] : Expt Γ→ Expt ∆

constructors

lit : (v : Valt) → Expt Γvar : (x : Vart Γ) → Expt Γarith : (op : ArithOp t) (e1 e2 : Expt Γ) → Expt Γcmp : (op : CmpOp t) (e1 e2 : Expt Γ) → Expbool Γ

Abel Dependently-Typed Compilation TYPES 2020 12 / 25

Page 13: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-typed syntax

Statements

assign : (x : Vart Γ) (e : Expt Γ) → Stmr Γ Γdecl : (t : Ty) → Stmr Γ (Γ.t)return : (e : Expr Γ) → Stmr Γ Γwhile : (e : Expbool Γ) (s : Stmr Γ Γ′) → Stmr Γ Γif : (e : Expbool Γ) (s1 : Stmr Γ Γ1) (s2 : Stmr Γ Γ2) → Stmr Γ Γ

Abel Dependently-Typed Compilation TYPES 2020 13 / 25

Page 14: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-formed machine code

Java Virtual Machine (JVM)

no registers

stack for evaluating expressions

local variable store (incl. function parameters)

(heap for objects)

method call handling behind the scenes

Abel Dependently-Typed Compilation TYPES 2020 14 / 25

Page 15: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-formed machine code

Java Virtual Machine (JVM) example

C-- Jasmin (symbolic JVM)

bool divides

(int p, int q)

{

return

(q / p) * p == q;

}

.method divides(II)I

iload_1 ;; q

iload_0 ;; p

idiv

iload_0 ;; p

imul

iload_1 ;; q

if_icmpeq L_true

iconst_0 ;; false

goto L_done

L_true: iconst_1 ;; true

L_done: ireturn

.end method

Abel Dependently-Typed Compilation TYPES 2020 15 / 25

Page 16: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-formed machine code

Evaluation Stack

JVM has local stack for evaluation of expressions.

Stack type ST = List Ty

Stack instruction SIΓ Φ Φ′

Γ : Cxt local variable store typingΦ : ST stack typing before instructionΦ′ : ST stack typing after

Constructors:

ldc : (i : Valint) → SIΓ Φ (Φ.int)load : (x : Vart Γ) → SIΓ Φ (Φ.t)store : (x : Vart Γ) → SIΓ (Φ.t) Φarith : (op : ArithOp t) → SIΓ (Φ.t.t) (Φ.t)

Instruction sequences SISΓ Φ Φ′: free category over SIΓ.

Abel Dependently-Typed Compilation TYPES 2020 16 / 25

Page 17: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-formed machine code

Variable typing administration

Variable declarations decl t : Stm Γ (Γ.t) are NOPs.

Needed in intrinsically typed machine language.

decl t : (Γ,Φ)→ (Γ.t,Φ)

Reconstruction in actual JVM by static analysis (bytecode verifier).

Machine type MT = Cxt× ST.

Abel Dependently-Typed Compilation TYPES 2020 17 / 25

Page 18: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-formed machine code

Jumps can go wrong

Bad jump:

;; Stack modification:

if_icmpeq L_true ;; [int,int] -> []

iconst_0 ;; [] -> [int]

L_true: istore_3 ;; [int] -> []

Jump target needs to have same stack typing as source.

Same for variable typing.

Labels are typed by “before” machine type Ξ of target.

Label context Labels = List MT.

A label is a de Bruijn index ` : LabelΞ Λ.

LabelΞ Λ ∼= ([Ξ] ⊆ Λ)

Abel Dependently-Typed Compilation TYPES 2020 18 / 25

Page 19: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-formed machine code

Jump targets need to exist

Semantics of a label is the code following it.

Each label needs to point to some code.

Two types of labels:

Join points for branches of if are lets.Back jumps to repeat body of while are fixs.

Abel Dependently-Typed Compilation TYPES 2020 19 / 25

Page 20: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-formed machine code

Join points: let

[[ if (e) s1; else s2; s ]] =

let l = [[s]]

l1 = [[s1]]; goto l

l2 = [[s2]]; goto l

in [[e]]; branch l1 l2

Abel Dependently-Typed Compilation TYPES 2020 20 / 25

Page 21: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-formed machine code

Back jumps: fix

[[ while (e) s0; s ]] =

let l2 = [[s]]

in fix l.

let l1 = [[s0]]; goto l

in [[e]]; branch l1 l2

Abel Dependently-Typed Compilation TYPES 2020 21 / 25

Page 22: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Well-formed machine code

Flowchart (control flow graph)

FCr Ξ Λ control flow graph

r return type of methodΞ machine state on entryΛ typed jump targets

Constructors:

exec : (i : SIΓ Φ Φ′) (fc : FCr (Γ,Φ′) Λ) → FCr (Γ,Φ) Λdecl : (t : Ty) (fc : FCr (Γ.t, ε) Λ) → FCr (Γ, ε) Λreturn : (e : Expr Γ) → FCr (Γ, ε) Λgoto : (` : LabelΞ Γ) → FCr Ξ Λbranch : (o : CmpOp t) (fc fc ′ : FCr (Γ,Φ) Λ) → FCr (Γ,Φ.t.t) Λlet : (fc ′ : FCr Ξ′ Λ) (fc : FCr Ξ (Λ.Ξ′)) → FCr Ξ Λfix : (fc : FCr Ξ (Λ.Ξ)) → FCr Ξ Λ

Abel Dependently-Typed Compilation TYPES 2020 22 / 25

Page 23: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Wrapping up

Back end

Code generation: translation from well-typed syntax to flow chartusing continuations.

Linearization: from flowcharts to basic blocks.

Printing: from basic blocks to Jasmin symbolic JVM.

Abel Dependently-Typed Compilation TYPES 2020 23 / 25

Page 24: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Wrapping up

Evaluation

When it type-checks, it works.

Had only 3 bugs in compiler on first run!

Agda programming requires hard thinking ahead.

Little proof effort.

Too hard for average beginning master student.

Full verification in progress:

Needs reasoning in sublist-category.Contributed categorical constructions (e.g. weak pushout) to Agdastandard library.

Abel Dependently-Typed Compilation TYPES 2020 24 / 25

Page 25: Type-preserving compilation via dependently typed syntax in Agdaabela/talkTYPES2020.pdf · 2020-03-04 · Introduction Method Implement compiler in a dependently-typed programming

Wrapping up

Related Work

Andrew Appell, Modern compiler implementation in C/Java/ML

Xavier Leroy et al., CompCert, in Coq

Magnus Myreen et al., CakeML, in HOL

DeepSpec project: Verified tool chain

Greg Morrisett et al., Typed Assembly Language

Alberto Pardo, Emmanuel Gunter, Miguel Pagano, Marcos Viera, AnInternalist Approach to Correct-by-Construction Compilers, PPDP’18:Terms indexed by semantics (in Agda)

Abel Dependently-Typed Compilation TYPES 2020 25 / 25