You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
semantics-2023/theories/type_systems/systemf/church_encodings.v

174 lines
4.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

From stdpp Require Import gmap base relations.
From iris Require Import prelude.
From semantics.lib Require Export debruijn.
From semantics.ts.systemf Require Import lang notation types bigstep tactics.
(** * Church encodings *)
Implicit Types
(Δ : nat)
(Γ : typing_context)
(v : val)
(α : var)
(e : expr)
(A : type).
Definition empty_type : type := : #0.
(** *** Unit *)
Definition unit_type : type := : #0 #0.
Definition unit_inh : val := Λ, λ: "x", "x".
Lemma unit_wf n : type_wf n unit_type.
Proof. solve_typing. Qed.
Lemma unit_inh_typed n Γ : TY n; Γ unit_inh : unit_type.
Proof. solve_typing. Qed.
(** *** Bool *)
Definition bool_type : type := : #0 #0 #0.
Definition bool_true : val := Λ, λ: "t" "f", "t".
Definition bool_false : val := Λ, λ: "t" "f", "f".
Definition bool_if e e1 e2 : expr := (e <> (λ: <>, e1)%E (λ: <>, e2)%E) unit_inh.
Lemma bool_true_typed n Γ : TY n; Γ bool_true : bool_type.
Proof. solve_typing. Qed.
Lemma bool_false_typed n Γ: TY n; Γ bool_false : bool_type.
Proof. solve_typing. Qed.
Lemma bool_if_typed n Γ e e1 e2 A :
type_wf n A
TY n; Γ e1 : A
TY n; Γ e2 : A
TY n; Γ e : bool_type
TY n; Γ bool_if e e1 e2 : A.
Proof.
intros. solve_typing.
apply unit_wf.
all: solve_typing.
Qed.
Lemma bool_if_true_red e1 e2 v :
is_closed [] e1
big_step e1 v
big_step (bool_if bool_true e1 e2)%E v.
Proof.
intros. bs_step_det.
Qed.
Lemma bool_if_false_red e1 e2 v :
is_closed [] e2
big_step e2 v
big_step (bool_if bool_false e1 e2)%E v.
Proof.
intros. bs_step_det.
Qed.
(** *** Product types *)
(* Using De Bruijn indices, we need to be a bit careful:
The binder introduced by [∀:] should not be visible in [A] and [B].
Therefore, we need to shift [A] and [B] up by one, using the renaming substitution [ren].
*)
Definition product_type (A B : type) : type := : (A.[ren (+1)] B.[ren (+1)] #0) #0.
Definition pair_val (v1 v2 : val) : val := Λ, λ: "p", "p" v1 v2.
Definition pair_expr (e1 e2 : expr) : expr :=
let: "x2" := e2 in
let: "x1" := e1 in
Λ, λ: "p", "p" "x1" "x2".
Definition proj1_expr (e : expr) : expr := e <> (λ: "x" "y", "x")%E.
Definition proj2_expr (e : expr) : expr := e <> (λ: "x" "y", "y")%E.
Lemma proj1_red v1 v2 :
is_closed [] v1
is_closed [] v2
big_step (proj1_expr (pair_val v1 v2)) v1.
Proof.
intros. bs_step_det.
rewrite subst_is_closed_nil; last done.
bs_step_det.
Qed.
Lemma proj2_red v1 v2 :
is_closed [] v1
is_closed [] v2
big_step (proj2_expr (pair_val v1 v2)) v2.
Proof.
intros. bs_steps_det.
Qed.
Lemma pair_red e1 e2 v1 v2 :
is_closed [] v2
is_closed [] e1
big_step e1 v1
big_step e2 v2
big_step (pair_expr e1 e2) (pair_val v1 v2).
Proof.
intros. bs_steps_det.
Qed.
Lemma proj1_typed n Γ e A B :
type_wf n A
type_wf n B
TY n; Γ e : product_type A B
TY n; Γ proj1_expr e : A.
Proof.
intros. solve_typing.
Qed.
Lemma proj2_typed n Γ e A B :
type_wf n A
type_wf n B
TY n; Γ e : product_type A B
TY n; Γ proj2_expr e : B.
Proof.
intros. solve_typing.
Qed.
(** We need to assume that x2 is not bound by Γ.
This is a bit annoying, as it puts a restriction on the context in which this typing rule
can be used.
Alternatively, we could parameterize the encoding of [pair_expr] by a name to use,
so that we can always choose a name for it that does not conflict with Γ.
*)
Lemma pair_expr_typed n Γ e1 e2 A B :
Γ !! "x2" = None
type_wf n A
type_wf n B
TY n; Γ e1 : A
TY n; Γ e2 : B
TY n; Γ pair_expr e1 e2 : product_type A B.
Proof.
intros.
solve_typing.
eapply typed_weakening; [done | | lia]. apply insert_subseteq. done.
Qed.
(** *** Church numerals *)
Definition nat_type : type := : #0 (#0 #0) #0.
Definition zero_val : val := Λ, λ: "z" "s", "z".
Definition num_val (n : nat) : val := Λ, λ: "z" "s", Nat.iter n (App "s") "z".
Definition succ_val : val := λ: "n", Λ, λ: "z" "s", "s" ("n" <> "z" "s").
Definition iter_val : val := λ: "n" "z" "s", "n" <> "z" "s".
Lemma zero_typed Γ n : TY n; Γ zero_val : nat_type.
Proof. solve_typing. Qed.
Lemma num_typed Γ n m : TY n; Γ num_val m : nat_type.
Proof.
solve_typing.
induction m as [ | m IH]; simpl.
- solve_typing.
- solve_typing.
Qed.
Lemma succ_typed Γ n :
TY n; Γ succ_val : (nat_type nat_type).
Proof.
solve_typing.
Qed.
Lemma iter_typed n Γ C :
type_wf n C
TY n; Γ iter_val : (nat_type C (C C) C).
Proof.
intros. solve_typing.
Qed.