survey around semantics for programming languages, and machine proof using coq
TRANSCRIPT
2008/07/16: enhanced at 07/22
Survey around Semantics for Programming Languages, and
Machine Proof using Coq
ichiyama ryoichi*1
1 Todays Summary• Survey for Type System and Programming Language
– Semantics and Proof– Various Languages (Type Systems for Lambda Calculus)– (Binder) Encoding Styles for Target Language
• Proof for Programming Language with Coq
2 My Motivation• Continuing work: Definitional interpreters, Gradual typing, ....• Challenge to Programming them with Coq
– toward my language• Learn the area around lang def with proof
– several methods, techniques, some application• Dependently typed language/programming• Category theory: F-Algebra,...• LATEX: slide, lstlisting, proof.sty
3 Table• * Coq basics• Semantics and Proof• Type Systems• Encoding Strategies
4 Coq Basics• Coq Proof Assistant: http://coq.inria.fr/
– Tools: CoqIde, coqtop, coqc, coqdoc, ...– Language features∗ Interactive∗ Modes: Programming/Proof(code generation)
· GALLINA/Ltac∗ Functional, Dependently Typed
· Calculus of Inductive Constructions (CIC)∗ User Defined Syntax (Sugar)∗ Module system
– Code Generation: OCaml, SML, Haskell,
5 Process of ProofProcess for proving with machine is:
• Define Structures and Functions for Proof Targets• Describe a Theorem to Prove• Prove It
Now, it defines a small expression language, then prove some trivialtheorems.
6 Example: Small Expression
n : nat#n : Expr
. . . ENum
a : Expr b : Expr
a + + b : Expr. . . EAdd
a : Expr b : Expr
a −− b : Expr. . . ESub
#n ⇒ n. . . EvalNum
a ⇒ n b ⇒ ma + + b ⇒ n + m
. . . EvalAdd
a ⇒ n b ⇒ ma −− b ⇒ n − m
. . . EvalSub
Fig. 1 Small Expression definition
• expr: #10 −−(#5 + +#2)• value: 3
7 Coq Program: Inductive, Functions
code 1 Small Expression Definition
1 (* data type definition *)2 Inductive Expr: Type :=3 | ENum (n: nat): Expr4 | EAdd (a: Expr) (b: Expr): Expr5 | ESub: Expr -> Expr -> Expr.6
7 (* function definition *)8 Definition natToExpr (n:nat): Expr :=9 ENum n.
10
11 Fixpoint eva l (e: Expr) {struct e}: nat :=12 match e with13 | ENum n => n14 | EAdd a b => ( eva l a) + ( e va l b)15 | ESub a b => ( eva l a) - ( e va l b)16 end.
8 Check and Evaluate
code 2 Check and Evaluate
1 (* check term type *)2 Check ( eva l (ESub (ENum 10) (EAdd (ENum 5) (ENum 2)))).3 (* print evaluated term *)4 Eval compute in5 ( eva l (ESub (ENum 10) (EAdd (ENum 5) (ENum 2)))).
code 3 Output on coqtop
1 Coq < Check ( e va l (ESub (ENum 10) (EAdd (ENum 5) (ENum 2)))).2 eva l (ESub (ENum 10) (EAdd (ENum 5) (ENum 2)))3 : nat4
5 Coq < Eval compute in6 ( eva l (ESub (ENum 10) (EAdd (ENum 5) (ENum 2)))).7 = 38 : nat
9 ProofExample Theorem:
• if (eval N) = n and (eval M) = m, then (eval N++M) = n+m
code 4 Proof example
1 (* proof *)2 Theorem add: forall (n m: nat) (N M: Expr),3 (eq ( eva l N) n) -> (eq ( eva l M) m) -> (eq ( e va l (EAdd N M)) (n + m)).4 Proof.5 intros n m N M H0 H1.6 unfold eva l .7 fold eva l .8 rewrite H0.9 rewrite H1.
10 reflexivity.11 Qed.
... To make proof, usually use interactive console: coqtop, CoqIDE
10 Proof StrategyIn general,
• From the goal, move all ”forall A” and ”A →” to hypotheses with”intro” tactic
• Then:– Make ”the goal is True” clear for the proof machine∗ The goal is always True under its hypotheses∗ tactics: rewriting, reduction, applying function, ...
– Find one of hypotheses always ”False”∗ Use ”inversion” tactic to it, then proof for the goal is end
– Destruct one of terms in the goal(mathematical induction)∗ then prove goals for each case.
11 Interactive proof editing
code 5 Proof example:start
1 Coq < Theorem add: forall (n m: nat) (N M: Expr),2 (eq ( eva l N) n) -> (eq ( eva l M) m) -> (eq ( e va l (EAdd N M)) (n + m)).3 1 subgoal4
5 ============================6 forall (n m : nat) (N M : Expr),7 eva l N = n -> eva l M = m -> eva l (EAdd N M) = n + m8
9 add < intros n m N M H0 H1.
code 6 Proof example:intros
1 add < intros n m N M H0 H1.2 1 subgoal3
4 n : nat5 m : nat6 N : Expr7 M : Expr8 H0 : eva l N = n9 H1 : eva l M = m
10 ============================11 eva l (EAdd N M) = n + m12
13 add < unfold e va l .
code 7 Proof example:unfold
1 add < unfold e va l .2 1 subgoal3 n : nat4 m : nat5 N : Expr6 M : Expr7 H0 : eva l N = n8 H1 : eva l M = m9 ============================
10 (fix e va l (e : Expr) : nat :=11 match e with12 | ENum n0 => n013 | EAdd a b => eva l a + eva l b14 | ESub a b => eva l a - eva l b15 end) N +16 (fix e va l (e : Expr) : nat :=17 match e with18 | ENum n0 => n019 | EAdd a b => eva l a + eva l b20 | ESub a b => eva l a - eva l b21 end) M = n + m22
23 add < fold e va l .
code 8 Proof example:fold
1 add < fold e va l .2 1 subgoal3
4 n : nat5 m : nat6 N : Expr7 M : Expr8 H0 : eva l N = n9 H1 : eva l M = m
10 ============================11 eva l N + eva l M = n + m12
13 add < rewrite H0; rewrite H1.
code 9 Proof example:rewrite
1 add < rewrite H0; rewrite H1.2 1 subgoal3
4 n : nat5 m : nat6 N : Expr7 M : Expr8 H0 : eva l N = n9 H1 : eva l M = m
10 ============================11 n + m = n + m12
13 add < reflexivity.
12 Interactive proof editing: cont
code 10 Proof example:reflexitivity and qed
1 add < reflexivity.2 Proof completed.3
4 add < Qed.5 intros n m N M H0 H1.6 unfold eva l in |- *.7 fold eva l in |- *.8 rewrite H0 in |- *; rewrite H1 in |- *.9 reflexivity.
10 add is defined11
12 Coq <
13 Proof generates function body definition
code 11 Proof is function definition
1 Coq < Print add.2 add =3 fun (n m : nat) (N M : Expr) (H0 : eva l N = n) (H1 : eva l M = m) =>4 eq_ind_r (fun n0 : nat => n0 + eva l M = n + m)5 (eq_ind_r (fun n0 : nat => n + n0 = n + m) (refl_equal (n + m)) H1) H06 : forall (n m : nat) (N M : Expr),7 eva l N = n -> eva l M = m -> eva l (EAdd N M) = n + m8
9
10 Argument scopes are [nat_scope nat_scope _ _ _ _]11
12 Coq <
• ”add” is function• Type of function ”add” is proposition for the Theorem• ”Theorem”, ”Lemma” is function: like ”Definition”
14 User Syntax Extension
code 12 Extend Syntax at ”scope”
1 (* user defined syntax and scope *)2 Notation "#␣n" := (ENum n) (at level 50): expr_scope.3 Notation "x␣++␣y" := (EAdd x y)4 (left associativity , at level 60) : expr_scope.5 Infix "--" := ESub6 (left associativity , at level 60) : expr_scope.7 Bind Scope expr_scope with Expr.8 Delimit Scope expr_scope with expr.
code 13 use scope
1 (* use defined syntax in the scope *)2 Check ( eva l (#10 -- (#5 ++ #2)) %expr).3 Eval compute in ( eva l (#10 -- (#5 ++ #2)) %expr).
15 Table• Coq basics• * Semantics and Proof• Type Systems• Encoding Strategies
16 Formal Semantics• To define language, semantics gives mathematical meaning to it.
– Syntax structure– Evaluator– Type Judgement
• Denotational Semantics: denotes language as mathmatical structure– Inductive, Function– total function, primitive recursive
• Operational Semantics: step by step computational sequence– substitution
• Axiomatic Semantics, Game Semantics
17 Example:Typed Expression Language
Expr := ETrue|EFalse|ENum (n : nat)|EEq a b|EIf c t fJudge : Expr → Type → Prop
⊢ ETrue : TBool. . . JTrue
⊢ EFalse : TBool. . . JFalse
n : nat⊢ ENum n : TNat
. . . JNum
⊢ a : TNat ⊢ b : TNat⊢ EEq a b : TBool
. . . JEq
⊢ c : TBool ⊢ t : T ⊢ f : T
⊢ EIf c t f : T. . . JIf
Fig. 2 Typed Expression Language definition
18 Denotational Semantics by Coq
• use meta language(coq) feature– dependent type inductive∗ Type judge for target language as coq type parameter
– define semantics as function– use coq object as value: includes coq function
19 Denotational Semantics code
code 14 Denotational semantics:syntax
1 (* operational semantics *)2 Require Import EqNat.3
4 (* type *)5 Inductive TypeT: Type :=6 | TBool: TypeT7 | TNat: TypeT.8
9 (* expr *)10 Inductive Expr: TypeT -> Type :=11 | ETrue: Expr TBool12 | EFalse: Expr TBool13 | ENum (n: nat): Expr TNat14 | EEq: Expr TNat -> Expr TNat -> Expr TBool15 | EIf: forall T, Expr TBool -> Expr T -> Expr T -> Expr T.
code 15 Denotational semantics:denotation
1 (* denotational semantics *)2 Definition denoteType (T: TypeT): Set :=3 match T with4 | TBool => bool5 | TNat => nat6 end.7 Fixpoint denoteExpr (T: TypeT) (expr: Expr T) {struct expr}: denoteType T :=8 match expr in (Expr t) return (denoteType t) with9 | ETrue => true
10 | EFalse => false11 | ENum n => n12 | EEq l r => beq_nat (denoteExpr _ l) (denoteExpr _ r)13 | EIf _ cond ifTrue ifFalse =>14 match (denoteExpr TBool cond) with15 | true => denoteExpr _ ifTrue16 | false => denoteExpr _ ifFalse17 end18 end.
code 16 Denotational semantics:check
1 (* example: if 5 == 10 then true else 7 == 8 end *)2 Check (denoteExpr _3 (EIf _ (EEq (ENum 5) (ENum 10)) ETrue (EEq (ENum 7) (ENum 8)))).4 Eval compute in (denoteExpr _5 (EIf _ (EEq (ENum 5) (ENum 10)) ETrue (EEq (ENum 7) (ENum 8)))).
20 Operational Semantics by coq• use first-order logic
– rule: parametric Inductive for ”Prop” instance: looks like Prolog rule– ”Prop” is builtin type: Prop := True or False
code 17 Operational semantics:syntax
1 (* operational semantics *)2 (* type *)3 Inductive TypeT: Type :=4 | TBool: TypeT5 | TNat: TypeT.6
7 (* expr *)8 Inductive Expr: Type :=9 | ETrue: Expr
10 | EFalse: Expr11 | ENum (n: nat): Expr12 | EEq (a b:Expr): Expr13 | EIf (cond ifTrue ifFalse: Expr): Expr.
code 18 Operational semantics:example term
1 Check (EIf (EEq (ENum 10) (ENum 5)) EFalse ETrue).
code 19 Operational semantics:judgement
1 (* type judgement *)2 Inductive Judge: Expr -> TypeT -> Prop :=3 | JTrue: Judge ETrue TBool4 | JFalse: Judge EFalse TBool5 | JNum: forall n:nat ,6 Judge (ENum n) TNat7 | JEq: forall (a b: Expr),8 Judge a TNat /\ Judge b TNat ->9 Judge (EEq a b) TBool
10 | JIf: forall (cond ifTrue ifFalse: Expr) (T: TypeT),11 Judge cond TBool /\ Judge ifTrue T /\ Judge ifFalse T ->12 Judge (EIf cond ifTrue ifFalse) T.
code 20 Type judgement with prolog
1 judge(eTrue , tBool).2 judge(eFalse , tBool ).3 judge(eNum(N), tNat) :-4 is_nat(N).5 judge(eEq(A, B), tBool) :-6 judge(A, tNat), judge(B, tNat).7 judge(eIf(Cond , IfTrue , IfFalse), T) :-8 judge(Cond , tBool), judge(IfTrue , T), judge(IfFalse , T).
code 21 Operational semantics:1-step reduction
1 (* small step reduction: each step substitute just one term *)2 Inductive Beta: Expr -> Expr -> Prop :=3 | BEq: forall (n: nat) (a b: Expr),4 Beta (EEq (ENum n) (ENum n)) ETrue5 | BNeq: forall (n m: nat) (a b: Expr),6 (n <> m) ->7 Beta (EEq (ENum n) (ENum m)) EFalse8 | BEqLeft: forall (a b c: Expr),9 Beta a c ->
10 Beta (EEq a b) (EEq c b)11 | BEqRight: forall (n:nat) (b c: Expr),12 Beta b c ->13 Beta (EEq (ENum n) b) (EEq (ENum n) c)14 | BIfTrue: forall (ifTrue ifFalse: Expr),15 Beta (EIf ETrue ifTrue ifFalse) ifFalse16 | BIfFalse: forall (ifTrue ifFalse: Expr),17 Beta (EIf EFalse ifTrue ifFalse) ifFalse18 | BIfCond: forall (cond c ifTrue ifFalse: Expr),19 Beta cond c ->20 Beta (EIf cond ifTrue ifFalse) (EIf c ifTrue ifFalse ).
code 22 Operational semantics:value normal form multi step
1 (* value *)2 Inductive Value: Expr -> Prop :=3 | VTrue: Value ETrue4 | VFalse: Value EFalse5 | VNum: forall n, Value (ENum n).6
7 (* normal form *)8 Definition normal (expr: Expr): Prop :=9 ~ exists e, Beta expr e.
10
11 (* multi step reduction *)12 Inductive Eval: Expr -> Expr -> Prop :=13 | EStep: forall (e1 e2 ej: Expr),14 Beta e1 e2 ->15 Eval e2 ej ->16 Eval e1 ej17 | EStop: forall (e: Expr),18 Eval e e.
21 Type safety
code 23 Operational semantics:propositions
1 (*In operational semantics ,2 progress and preservation => type safe *)3
4 (* progress *)5 Theorem p rog r e s s : forall (e1: Expr) (T: TypeT),6 Judge e1 T -> Value e1 \/ (exists e2 , Beta e1 e2).7 Admitted.8
9 (* preservation *)10 Theorem preservation: forall (e1 e2: Expr) (T: TypeT),11 Judge e1 T /\ Beta e1 e2 -> Judge e2 T.12 Admitted.13
14 (* strong normalization *)15 Theorem strong: forall e1 , exists e2,16 Eval e1 e2 -> normal e2.17 Admitted.18
19 (* they are trivial from induction when manual proof , but not for machine *)
22 Defining RulesTwo styles for defining rules:
• as Function– pros: proof is shorter– cons: total body definition at first– tactics: unfold, fold
• as Inductive of Prop– pros: constructive, partially– cons: proof is longer: for all induction cases– tactics: apply, constructor
23 Table• Coq basics• Semantics and Proof• * Type Systems• Encoding Strategies
24 Type Systems for Lambda CalculusType systems
• Simply Typed Lambda Calculus(STLC)• System F : STLC with Type abstraction• Edinburgh LF: dependent type, Kind/Type/Term layer• Dependently Typed language: Type and Term are same layer
Show the definitions by syntax written in coq.
25 STLCSyntax
T = t|T1 → T2
E = x|E1 E2|λx : T.E
code 24 STLC Syntax
1 Require Import String.2
3 (* types for terms *)4 Inductive TypeT: Type :=5 | TTAtom: TypeT6 | TTFunc: TypeT -> TypeT -> TypeT.7
8 (* terms *)9 Inductive Term: Type :=
10 | TVar: string -> Term11 | TApp: Term -> Term -> Term12 | TAbs: string -> TypeT -> Term -> Term.
26 System F
T = t|T1 → T2|α|∀α.T
E = x|E1 E2|λx : T.E|Λα.T |E T
code 25 System F Syntax
1 (* types for terms *)2 Inductive TypeT: Type :=3 | TTAtom: TypeT4 | TTFunc: TypeT -> TypeT -> TypeT5 | TTVar: string -> TypeT6 | TTAll: string -> TypeT -> TypeT.7
8 (* terms *)9 Inductive Term: Type :=
10 | TVar: string -> Term11 | TApp: Term -> Term -> Term12 | TAbs: string -> TypeT -> Term -> Term13 | TTApp: Term -> TypeT -> Term14 | TTAbs: string -> Term -> Term.
27 LF• LF: Edingurgh Logical Framework
– A Framework for Defining Logics - Harper, Honsell, Plotkin *1
– Lambda Calculus with Dependent Type– Syntax: Kind / Family / Object
• Defining formal semantics on LF is useful– Higher Order Abstract Syntax (HOAS)
K = Type|T → K
T = t|T1 → T2|α|∀t : T1.T2|T E
E = x|E1 E2|λx : T.E
例: x : (∀n : Nat.V ec n).x
*1 http://citeseer.ist.psu.edu/harper87framework.html
code 26 LF Syntax
1 (* kinds , types , terms *)2 Inductive Kind: Type :=3 | KTop: Kind4 | KFunc: TypeT -> Kind -> Kind5 with TypeT: Type :=6 | TTAtom: TypeT7 | TTAbs: string -> TypeT -> TypeT -> TypeT8 | TTFunc: TypeT -> TypeT -> TypeT9 | TTApp: TypeT -> Term -> TypeT
10 with Term: Type :=11 | TVar: string -> Term12 | TApp: Term -> Term -> Term13 | TAbs: string -> TypeT -> Term -> Term.
28 Dependenty Typed Lambda Calculus
T = Type|t|T1 → T2|T1 T2|λt : T1.T2
code 27 Dependently Typed
1 (* terms *)2 Inductive Term: Type :=3 | TTop: Term4 | TVar: string -> Term5 | TFunc: Term -> Term -> Term6 | TApp: Term -> Term -> Term7 | TAbs: string -> Term -> Term -> Term.
29 Table• Coq basics• Semantics and Proof• Type Systems• * Encoding Strategies
30 Big Problem: α renaming for lambda calculus• lambda calculus needs α renaming• ex: (λx : A.λy : B.x)(λz : C.yz)
– ̸= λy : B.(λz : C.yz))– = λy0 : B.(λz : C.yz))
• Free variables vs. Bind variables• label comflict check, new name assign
Rules for proof explode when to write on formal systems.
• go more indirect representations• differ from proof by hand
Various strategies used on lambda calculus encoding; e.g. Fsub *2 atPOPLmark Challenge *3
*2 System F + structural subtyping + pattern matching*3 http://alliance.seas.upenn.edu/∼plclub/cgi-bin/poplmark/
31 Encoding Strategies
from ”Engeneering Formal Metatheory” *4, ”Parametric Higher-OrderAbstract Syntax for Mechanized Semantics” *5
• Concrete(First-Order) Approach– syntax tree consists algebraic data
• Hiegher-Order Approach– syntax tree use ”meta” language function object– e.g. HOAS: Abs : (Expr → Expr) → Expr– Abs(fun f ⇒ (Abs(fun x ⇒ App f x)))
*4 http://www.chargueraud.org/arthur/research/2007/binders/
binders popl 08.pdf*5 http://adam.chlipala.net/papers/PhoasICFP08/
32 category of Encoding Strategies• Concrete Approach
– Homogeneous apprach: single variable notation∗ raw expression∗ de Bruijn index∗ nominal logic
– split parameter(free variable) and (bound) variable∗ locally named∗ locally nameless
• Higher-Order Approach– Higher Order Abstract Syntax(HOAS)– weak HOAS– parametric HOAS
33 Raw expression
code 28 Raw expression: syntax
1 (* raw encoding: STLC *)2 Require Import String.3
4 (* types for terms *)5 Inductive TypeT: Type :=6 | TTAtom: TypeT7 | TTFunc: TypeT -> TypeT -> TypeT.8
9 (* terms *)10 Inductive Term: Type :=11 | TVar: string -> Term12 | TApp: Term -> Term -> Term13 | TAbs: string -> TypeT -> Term -> Term.
code 29 Raw expression: env and context
1 (* environment for evaluation: list (string , Term) *)2 Inductive Env: Type :=3 | ENil: Env4 | ECons: string -> Term -> Env -> Env.5
6 (* type environment for type system: list (string , TypeT) *)7 Inductive Context: Type :=8 | CNil: Context9 | CCons: string -> TypeT -> Context -> Context.
code 30 Raw expression: example
1 (* example2 this term needs alpha renaming to fresh names in evaluation:3
4 (\x:A.\y->x) (\z:A.y z)5 =/=> (\y (\z:A.y z))6 ==> (\y1 (\z:A.y z))7 *)8 Check (TApp (TAbs "x" (TTFunc TTAtom TTAtom)9 (TAbs "y" TTAtom (TVar "x")))
10 (TAbs "z" TTAtom (TApp (TVar "y") (TVar "z")))).
34 de Bruijn indexChange variable to index: number of outer binders: TAbs
• λx.λy.yx is λ.λ.0 1
code 31 de Bruijn index: syntax
1 (* de Bruijn index: STLC *)2
3 (* type *)4 Inductive TypeT: Type :=5 | TTAtom: TypeT6 | TTFunc: TypeT -> TypeT -> TypeT.7
8 (* term: variable is indexed: level for outer TAbs binders (0..) *)9 Inductive Term: Type :=
10 | TVar: nat -> Term11 | TApp: Term -> Term -> Term12 | TAbs: TypeT -> Term -> Term.
code 32 de Bruijn index: env and context
1 (* env: list Term *)2 Inductive Env: Type :=3 | ENil: Env4 | ECons: Term -> Env -> Env.5
6 (* context: list TypeT *)7 Inductive Context: Type :=8 | CNil: Context9 | CCons: TypeT -> Context -> Context.
Variable access is only list index access
code 33 de Bruijn index: example
1 (* no free vars2 \x:A.\y:A.x3 *)4 Check (TAbs TTAtom (TAbs TTAtom (TVar 1))).
35 Nominal logickeep renaming history as ”Swap” expression. from swapping relation,consists nominal logic
code 34 Nominal logic
1 (* nominal logic: not complete *)2 (* see: http :// arxiv.org/PS_cache/cs/pdf /0511/0511025 v1.pdf *)3 Require Import String.4
5 (* types for terms *)6 Inductive TypeT: Type :=7 | TAtom: TypeT8 | TFunc: TypeT -> TypeT -> TypeT.9
10 (* terms *)11 Inductive Term: Type :=12 | TVar: string -> Term13 | TApp: Term -> Term -> Term14 | TAbs: Term -> TypeT -> Term -> Term15 | TSwap: string -> string -> Term -> Term.
code 35 Nominal logic: logic for swap
1 (* logical combinator and rules:2 swap , fresh , abstraction , new -quantifier ,3 new fresh name could be found always , equiv for swapping4
5 TSwap a b (TVar b) == a6 TSwap a b (TVar a) == b7 TSwap a b (TVar c) == c8 TSwap a b (TApp f t) == TApp f (TSwap a b t)9 TSwap a b (TAbs c k t) == TAbs (TSwap a b c) k (TSwap a b t)
10 *)
36 Nominal PackageProvide nominal subsystem as package module.
code 36 Nominal package
1 (* nominal packaged *)2 (* see: http :// www.cis.upenn.edu/~ baydemir/nominal -reasoning -in -coq/ *)3 Require Import String.4
5 (* terms for nominal package *)6 Parameter Term: Type.7 Parameter Swap: string -> string -> Term -> Term.8 (* and logic for freshness , abstraction , new quantifier , ... *)
code 37 use Nominal package
1 (* types *)2 Inductive TypeT: Type :=3 | TAtom: TypeT4 | TFunc: TypeT -> TypeT -> TypeT.5
6 (* Define terms as Parameter for package type *)7 Parameter Var: string -> Term.8 Parameter App: Term -> Term -> Term.9 Parameter Abs: Term -> TypeT -> Term -> Term.
10
11 (* set axioms around user terms for support nominal package.12
13 Swap a b (Var b) == a14 Swap a b (Var a) == b15 Swap a b (Var c) == c16 Swap a b (App f t) == App f (Swap a b t)17 Swap a b (Abs c k t) == Abs (Swap a b c) k (Swap a b t)18 *)
37 Locally named
code 38 Locally named
1 (* locally named: STLC *)2 Require Import String.3
4 (* types for terms *)5 Inductive TypeT: Type :=6 | TTAtom: TypeT7 | TTFunc: TypeT -> TypeT -> TypeT.8
9 (* terms *)10 Inductive Term: Type :=11 | TFVar: string -> Term12 | TBVar: string -> Term13 | TApp: Term -> Term -> Term14 | TAbs: string -> TypeT -> Term -> Term.
38 Locally nameless• Global parameter use name• Local varible use de Bruijn index• Change global to local by converter when bind variable
code 39 Locally nameless: syntax
1 Require Import String.2
3 (* locally nameless representation *)4 Inductive TypeT: Type :=5 | TTAtom: TypeT6 | TTFunc: TypeT -> TypeT -> TypeT.7
8 (* terms: two type variables: indexed bind var and named free var *)9 Inductive Term: Type :=
10 | TBVar: nat -> Term11 | TFVar: string -> Term12 | TApp: Term -> Term -> Term13 | TAbs: string -> TypeT -> Term -> Term.
code 40 Locally nameless: converter for bind variable
1 (* close: make TAbs from name and body(includes the name as free var) *)2 Fixpoint replace_fvar (x: string) (n: nat) (t: Term) {struct t}: Term :=3 match t with4 | TFVar y => match (string_dec x y) with5 | left _ => TBVar n6 | right _ => t7 end8 | TBVar i => TBVar i9 | TApp t1 t2 => TApp (replace_fvar x n t1) (replace_fvar x n t2)
10 | TAbs y ty b => TAbs y ty (replace_fvar x (n+1) b)11 end.12 Definition close (x: string) (type: TypeT) (body: Term): Term :=13 TAbs x type (replace_fvar x 0 body).
code 41 Locally nameless: example
1 (* example: (\x:A->A.y x) (\y:A.y)2 *)3 Check (TApp (close "x" (TTFunc TTAtom TTAtom)4 (TApp (TFVar "y") (TFVar "x")))5 (close "y" TTAtom (TFVar "y"))).6
7 Eval compute in8 (TApp (close "x" (TTFunc TTAtom TTAtom)9 (TApp (TFVar "y") (TFVar "x")))
10 (close "y" TTAtom (TFVar "y"))).
code 42 Locally nameless: Eval compute output
1 = TApp (TAbs "x" (TTFunc TTAtom TTAtom) (TApp (TFVar "y") (TBVar 0)))2 (TAbs "y" TTAtom (TBVar 0))3 : Term
39 HOAS
code 43 HOAS: syntax
1 (* HOAS: but cannot compile with coq *)2
3 (* types for terms *)4 Inductive TypeT: Type :=5 | TTAtom: TypeT6 | TTFunc: TypeT -> TypeT -> TypeT.7
8 (* terms: TAbs body is function: param is used as var *)9 Inductive Term: Type :=
10 | TVar: Term (* free vars *)11 | TApp: Term -> Term -> Term12 | TAbs: TypeT -> (Term -> Term) -> Term.13
14 (* TAbs ’s 2nd parameter type: Term ->Term is contra -variant ,15 so its Inductive cannot be defined/compiled *)
code 44 HOAS: example
1 (* HOAS example:2 \x:A.3 \y:A.x4 *)5 Check (TAbs TTAtom (fun (x: Term) =>6 (TAbs TTAtom (fun (y: Term) => x)))).
40 Weak HOAS
code 45 Weak HOAS: syntax
1 (* Weak HOAS *)2 Require Import String.3
4 (* types for terms *)5 Inductive TypeT: Type :=6 | TTAtom: TypeT7 | TTFunc: TypeT -> TypeT -> TypeT.8
9 (* terms: TAbs body is function: param is used as var *)10 Inductive Term: Type :=11 | TVar: string -> Term12 | TApp: Term -> Term -> Term13 | TAbs: TypeT -> (string -> Term) -> Term.
code 46 Weak HOAS: example
1 (* example:2 \x:A. ->3 \y:A. ->4 x5 *)6 Check (TAbs TTAtom (fun (x: string) =>7 (TAbs TTAtom (fun (y: string) =>8 TVar x)))).
code 47 Weak HOAS: infinite example
1 (* can write/compile infinite looped HOAS term , but cannot prove2 ex: (\x->x x) (\x->x x)3 *)4 Check (TApp (TAbs (TTFunc TTAtom TTAtom)5 (fun (x: string) => TApp (TVar x) (TVar x)))6 (TAbs (TTFunc TTAtom TTAtom)7 (fun (x: string) => TApp (TVar x) (TVar x)))).
41 PHOASdependently typed term with variable type and term type
code 48 PHOAS: syntax
1 (* Parametric HOAS2 http :// adam.chlipala.net/papers/PhoasICFP08/ *)3
4 (* types for terms *)5 Inductive TypeT: Type :=6 | TTAtom: TypeT7 | TTFunc: TypeT -> TypeT -> TypeT.8
9 (* terms: TAbs body is function: param is used as var *)10 Inductive Term: (TypeT -> Type) -> TypeT -> Type :=11 | TVar: forall var t,12 var t -> Term var t13 | TApp: forall var t1 t2,14 Term var (TTFunc t1 t2) -> Term var t1 -> Term var t215 | TAbs: forall var t1 t2,16 (var t1 -> Term var t2) -> Term var (TTFunc t1 t2).
code 49 PHOAS: example
1 (* example:2 \x:A. ->3 \y:A. ->4 x5 *)6 Check (fun _ =>7 TAbs _ _ _ (fun x =>8 TAbs _ _ _ (fun y =>9 TVar _ _ x))) :
10 (forall var , Term var (TTFunc TTAtom (TTFunc TTAtom TTAtom ))).
code 50 PHOAS: output
1 (fun H : TypeT -> Type =>2 TAbs H TTAtom (TTFunc TTAtom TTAtom)3 (fun x : H TTAtom =>4 TAbs H TTAtom TTAtom (fun _ : H TTAtom => TVar H TTAtom x)))5 :forall var : TypeT -> Type ,6 Term var (TTFunc TTAtom (TTFunc TTAtom TTAtom ))7 : forall var : TypeT -> Type ,8 Term var (TTFunc TTAtom (TTFunc TTAtom TTAtom ))
42 Summary of Today’s• writing semantics with coq• calculus and type system• binder encoding approach
My Impressions:
• Very hard to prove even if it is trivial proof by hand• There are many proof tactics, difficult how to use it• Challenging
43 Ommitted Theme• Features for target languages
– Type relation: subtyping,...– Record, Pattern matching– Recursive, Fixed point– Imperative: sequence, memory
• and its proof methods• Translate between target languages• Coq
– Axiom, well-founded– CoInductive– Ltac languages *6
*6 add as appendix
Appendix A Frequently used TacticsWhen remark equation
code 51 tactics for equation
1 (*2 rewrite H: replace terms by left hand side of equation H in hypothesis3 rewrite <- H: replace terms by right hand side of4 equation H in hypothesis5 subst: replace terms by lhs of all equations in hypothesis ,6 and remove the equations from hypo7 reflexivity: Proof is success when goal is just reflective: A = A8 *)
When remark ”type”*7 of TERM
code 52 tactics for type of term
1 (*2 exact TERM: check the goal is a type of the TERM.3 apply TERM: check the goal is a type of codomain of the TERM ,4 then goal becomes a type of domain of it5 *)
*7 right hand side of ”:”
When remark ”definition” of Function
code 53 tactics for definition of function
1 (*2 unfold FUNC: repeat rewrite FUNC to its definition and3 reduce by beta and case matching4 fold FUNC: rewrite the definition of FUNC to FUNC5 *)
When remark ”pattern” of Inductive
code 54 tactics for Inductive
1 (*2 destruct IDENT : split the current goal to subgoals3 by each constructors of the IDENT type.4 induction IDENT: similar to "destruct"5 constructor: check that the current goal is6 one of constructor patterns of the goal ’s.7 *)
When remark ”exists”, or defer the pattern matching by ”meta variable”
code 55 tactics for meta-variable
1 (*2 exists TERM: use TERM as example of "exists" quantifier3 econstructor: apply constructor4 with remaining "exists" as a meta -variable5 eapply TERM: apply TERM with remaining6 unclear parameters and "exists" as meta -variables7 instantiate (NUM := TERM): replace meta -variable ?NUM with TERM.8 *)
All ”meta-variable”s must not exist in the end of the proof.At the end, remove unused meta-variables with ”instanciate” when youuse ”eapply” with term which has many parameters.
When remark Hypothesis
code 56 tactics for hypothesis
1 (*2 inversion HYPO: check False hypothesis or destruct.3 assert TERM: add (HYPO: TERM) in hypothesis list of the current goal.4 *)
When remark automatic proving
code 57 tactics for auto
1 (*2 omega: check when the current goal is constructed3 by only nat and it is True.4 Requires library import: "Require Import Omega ."5 tauto: the goal forms tautology: A -> A or ~A \/ A6 trivial: ?7 auto: ?8 *)
Appendix B Syntax for Compound Tactics
code 58 syntax for compound tactics
1 (* syntax for using multiple tactics at once2 TACT; TACT: apply TACTs sequence to the goal.3 TACT0; [ TACT1 | TACT2 | ... ]: TACT0 generates multiple subgoals ,4 apply the TACTn to each subgoals.5
6 repeat TACT: apply TACT reqatedly until it fails.7 do NUM TACT: apply TACT at just NUM times.8 try TACT: apply TACT , if fails then undo progresses while doing TACT9
10 progress TACT: apply TACT , if no change goal , then fail11 TACT1 || TACT2: apply TACT1 if TACT1 "fails" then apply TACT2.12 first [TACT1 | TACT2 | ...]:13 apply TACTn. if TACTn fails , then apply TACTn +1.14 fails if all TACTs failed.15 solve [TACT1 | TACT2 | ...]:16 apply TACTn. if TACTn unsolves goal , then apply TACTn +117 fails if unsolved.18 *)
Appendix C Defining by Ltacfor example:
code 59 define a tactic
1 Ltac unfoldfold f := unfold f; fold f.