From semantics.ts.systemf_mu Require Export lang. Set Default Proof Using "Type". (** Coercions to make programs easier to type. *) Coercion of_val : val >-> expr. Coercion LitInt : Z >-> base_lit. Coercion LitBool : bool >-> base_lit. Coercion App : expr >-> Funclass. Coercion Var : string >-> expr. (** Define some derived forms. *) Notation Let x e1 e2 := (App (Lam x e2) e1) (only parsing). Notation Seq e1 e2 := (Let BAnon e1 e2) (only parsing). Notation Match e0 x1 e1 x2 e2 := (Case e0 (Lam x1 e1) (Lam x2 e2)) (only parsing). (* No scope for the values, does not conflict and scope is often not inferred properly. *) Notation "# l" := (LitV l%Z%V%stdpp) (at level 8, format "# l"). Notation "# l" := (Lit l%Z%E%stdpp) (at level 8, format "# l") : expr_scope. (** Syntax inspired by Coq/Ocaml. Constructions with higher precedence come first. *) Notation "( e1 , e2 , .. , en )" := (Pair .. (Pair e1 e2) .. en) : expr_scope. Notation "( e1 , e2 , .. , en )" := (PairV .. (PairV e1 e2) .. en) : val_scope. Notation "'match:' e0 'with' 'InjL' x1 => e1 | 'InjR' x2 => e2 'end'" := (Match e0 x1%binder e1 x2%binder e2) (e0, x1, e1, x2, e2 at level 200, format "'[hv' 'match:' e0 'with' '/ ' '[' 'InjL' x1 => '/ ' e1 ']' '/' '[' | 'InjR' x2 => '/ ' e2 ']' '/' 'end' ']'") : expr_scope. Notation "'match:' e0 'with' 'InjR' x1 => e1 | 'InjL' x2 => e2 'end'" := (Match e0 x2%binder e2 x1%binder e1) (e0, x1, e1, x2, e2 at level 200, only parsing) : expr_scope. Notation "()" := LitUnit : val_scope. Notation "e1 + e2" := (BinOp PlusOp e1%E e2%E) : expr_scope. Notation "e1 - e2" := (BinOp MinusOp e1%E e2%E) : expr_scope. Notation "e1 * e2" := (BinOp MultOp e1%E e2%E) : expr_scope. Notation "e1 ≤ e2" := (BinOp LeOp e1%E e2%E) : expr_scope. Notation "e1 = e2" := (BinOp EqOp e1%E e2%E) : expr_scope. Notation "e1 < e2" := (BinOp LtOp e1%E e2%E) : expr_scope. (*Notation "~ e" := (UnOp NegOp e%E) (at level 75, right associativity) : expr_scope.*) Notation "'if:' e1 'then' e2 'else' e3" := (If e1%E e2%E e3%E) (at level 200, e1, e2, e3 at level 200) : expr_scope. Notation "λ: x , e" := (Lam x%binder e%E) (at level 200, x at level 1, e at level 200, format "'[' 'λ:' x , '/ ' e ']'") : expr_scope. Notation "λ: x y .. z , e" := (Lam x%binder (Lam y%binder .. (Lam z%binder e%E) ..)) (at level 200, x, y, z at level 1, e at level 200, format "'[' 'λ:' x y .. z , '/ ' e ']'") : expr_scope. Notation "λ: x , e" := (LamV x%binder e%E) (at level 200, x at level 1, e at level 200, format "'[' 'λ:' x , '/ ' e ']'") : val_scope. Notation "λ: x y .. z , e" := (LamV x%binder (Lam y%binder .. (Lam z%binder e%E) .. )) (at level 200, x, y, z at level 1, e at level 200, format "'[' 'λ:' x y .. z , '/ ' e ']'") : val_scope. Notation "'let:' x := e1 'in' e2" := (Lam x%binder e2%E e1%E) (at level 200, x at level 1, e1, e2 at level 200, format "'[' 'let:' x := '[' e1 ']' 'in' '/' e2 ']'") : expr_scope. Notation "e1 ;; e2" := (Lam BAnon e2%E e1%E) (at level 100, e2 at level 200, format "'[' '[hv' '[' e1 ']' ;; ']' '/' e2 ']'") : expr_scope. Notation "'Λ' , e" := (TLam e%E) (at level 200, e at level 200, format "'[' 'Λ' , '/ ' e ']'") : expr_scope. Notation "'Λ' , e" := (TLamV e%E) (at level 200, e at level 200, format "'[' 'Λ' , '/ ' e ']'") : val_scope. (* the [e] always needs to be paranthesized, due to the level (chosen to make this cooperate with the [App] coercion) *) Notation "e '<>'" := (TApp e%E) (at level 10) : expr_scope. (*Check ((Λ, #4) <>)%E.*) (*Check (((λ: "x", "x") #5) <>)%E.*) Notation "'pack' e" := (Pack e%E) (at level 200, e at level 200) : expr_scope. Notation "'pack' v" := (PackV v%V) (at level 200, v at level 200) : val_scope. Notation "'unpack' e1 'as' x 'in' e2" := (Unpack x%binder e1%E e2%E) (at level 200, e1, e2 at level 200, x at level 1) : expr_scope. Notation "'roll' e" := (Roll e%E) (at level 200, e at level 200) : expr_scope. Notation "'roll' v" := (RollV v%E) (at level 200, v at level 200) : val_scope. Notation "'unroll' e" := (Unroll e%E) (at level 200, e at level 200) : expr_scope.