Qcert.NRAEnv.Typing.TcNRAEnv
Typing for NRA
Section typ.
Context {m:basic_model}.
Context (τconstants:tbindings).
Inductive cnraenv_type : cnraenv → rtype → rtype → rtype → Prop :=
| ANTID {τenv τ} :
cnraenv_type ANID τenv τ τ
| ANTConst {τenv τin τout} c :
data_type (normalize_data brand_relation_brands c) τout → cnraenv_type (ANConst c) τenv τin τout
| ANTBinop {τenv τin τ₁ τ₂ τout} b op1 op2 :
binOp_type b τ₁ τ₂ τout →
cnraenv_type op1 τenv τin τ₁ →
cnraenv_type op2 τenv τin τ₂ →
cnraenv_type (ANBinop b op1 op2) τenv τin τout
| ANTUnop {τenv τin τ τout} u op :
unaryOp_type u τ τout →
cnraenv_type op τenv τin τ →
cnraenv_type (ANUnop u op) τenv τin τout
| ANTMap {τenv τin τ₁ τ₂} op1 op2 :
cnraenv_type op1 τenv τ₁ τ₂ →
cnraenv_type op2 τenv τin (Coll τ₁) →
cnraenv_type (ANMap op1 op2) τenv τin (Coll τ₂)
| ANTMapConcat {τenv τin τ₁ τ₂ τ₃} op1 op2 pf1 pf2 pf3 :
cnraenv_type op1 τenv (Rec Closed τ₁ pf1) (Coll (Rec Closed τ₂ pf2)) →
cnraenv_type op2 τenv τin (Coll (Rec Closed τ₁ pf1)) →
rec_concat_sort τ₁ τ₂ = τ₃ →
cnraenv_type (ANMapConcat op1 op2) τenv τin (Coll (Rec Closed τ₃ pf3))
| ANTProduct {τenv τin τ₁ τ₂ τ₃} op1 op2 pf1 pf2 pf3 :
cnraenv_type op1 τenv τin (Coll (Rec Closed τ₁ pf1)) →
cnraenv_type op2 τenv τin (Coll (Rec Closed τ₂ pf2)) →
rec_concat_sort τ₁ τ₂ = τ₃ →
cnraenv_type (ANProduct op1 op2) τenv τin (Coll (Rec Closed τ₃ pf3))
| ANTSelect {τenv τin τ} op1 op2 :
cnraenv_type op1 τenv τ Bool →
cnraenv_type op2 τenv τin (Coll τ) →
cnraenv_type (ANSelect op1 op2) τenv τin (Coll τ)
| ANTDefault {τenv τin τ} op1 op2 :
cnraenv_type op1 τenv τin (Coll τ) →
cnraenv_type op2 τenv τin (Coll τ) →
cnraenv_type (ANDefault op1 op2) τenv τin (Coll τ)
| ANTEither {τenv τl τr τout} opl opr :
cnraenv_type opl τenv τl τout →
cnraenv_type opr τenv τr τout →
cnraenv_type (ANEither opl opr) τenv (Either τl τr) τout
| ANTEitherConcat {τenv τin rll pfl rlr pfr rlo pfo lo ro} op1 op2 pflo pfro :
cnraenv_type op1 τenv τin (Either (Rec Closed rll pfl) (Rec Closed rlr pfr)) →
cnraenv_type op2 τenv τin (Rec Closed rlo pfo) →
rec_concat_sort rll rlo = lo →
rec_concat_sort rlr rlo = ro →
cnraenv_type (ANEitherConcat op1 op2) τenv τin (Either (Rec Closed lo pflo) (Rec Closed ro pfro))
| ANTApp {τenv τin τ1 τ2} op2 op1 :
cnraenv_type op1 τenv τin τ1 →
cnraenv_type op2 τenv τ1 τ2 →
cnraenv_type (ANApp op2 op1) τenv τin τ2
| ANTGetConstant {τenv τin τout} s :
tdot τconstants s = Some τout →
cnraenv_type (ANGetConstant s) τenv τin τout
| ANTEnv {τenv τin} :
cnraenv_type ANEnv τenv τin τenv
| ANTAppEnv {τenv τenv' τin τ2} op2 op1 :
cnraenv_type op1 τenv τin τenv' →
cnraenv_type op2 τenv' τin τ2 →
cnraenv_type (ANAppEnv op2 op1) τenv τin τ2
| ANTMapEnv {τenv τin τ₂} op1 :
cnraenv_type op1 τenv τin τ₂ →
cnraenv_type (ANMapEnv op1) (Coll τenv) τin (Coll τ₂).
End typ.
Notation "Op ▷ A >=> B ⊣ C ; E" := (cnraenv_type C Op E A B) (at level 70).
Context {m:basic_model}.
Context (τconstants:tbindings).
Inductive cnraenv_type : cnraenv → rtype → rtype → rtype → Prop :=
| ANTID {τenv τ} :
cnraenv_type ANID τenv τ τ
| ANTConst {τenv τin τout} c :
data_type (normalize_data brand_relation_brands c) τout → cnraenv_type (ANConst c) τenv τin τout
| ANTBinop {τenv τin τ₁ τ₂ τout} b op1 op2 :
binOp_type b τ₁ τ₂ τout →
cnraenv_type op1 τenv τin τ₁ →
cnraenv_type op2 τenv τin τ₂ →
cnraenv_type (ANBinop b op1 op2) τenv τin τout
| ANTUnop {τenv τin τ τout} u op :
unaryOp_type u τ τout →
cnraenv_type op τenv τin τ →
cnraenv_type (ANUnop u op) τenv τin τout
| ANTMap {τenv τin τ₁ τ₂} op1 op2 :
cnraenv_type op1 τenv τ₁ τ₂ →
cnraenv_type op2 τenv τin (Coll τ₁) →
cnraenv_type (ANMap op1 op2) τenv τin (Coll τ₂)
| ANTMapConcat {τenv τin τ₁ τ₂ τ₃} op1 op2 pf1 pf2 pf3 :
cnraenv_type op1 τenv (Rec Closed τ₁ pf1) (Coll (Rec Closed τ₂ pf2)) →
cnraenv_type op2 τenv τin (Coll (Rec Closed τ₁ pf1)) →
rec_concat_sort τ₁ τ₂ = τ₃ →
cnraenv_type (ANMapConcat op1 op2) τenv τin (Coll (Rec Closed τ₃ pf3))
| ANTProduct {τenv τin τ₁ τ₂ τ₃} op1 op2 pf1 pf2 pf3 :
cnraenv_type op1 τenv τin (Coll (Rec Closed τ₁ pf1)) →
cnraenv_type op2 τenv τin (Coll (Rec Closed τ₂ pf2)) →
rec_concat_sort τ₁ τ₂ = τ₃ →
cnraenv_type (ANProduct op1 op2) τenv τin (Coll (Rec Closed τ₃ pf3))
| ANTSelect {τenv τin τ} op1 op2 :
cnraenv_type op1 τenv τ Bool →
cnraenv_type op2 τenv τin (Coll τ) →
cnraenv_type (ANSelect op1 op2) τenv τin (Coll τ)
| ANTDefault {τenv τin τ} op1 op2 :
cnraenv_type op1 τenv τin (Coll τ) →
cnraenv_type op2 τenv τin (Coll τ) →
cnraenv_type (ANDefault op1 op2) τenv τin (Coll τ)
| ANTEither {τenv τl τr τout} opl opr :
cnraenv_type opl τenv τl τout →
cnraenv_type opr τenv τr τout →
cnraenv_type (ANEither opl opr) τenv (Either τl τr) τout
| ANTEitherConcat {τenv τin rll pfl rlr pfr rlo pfo lo ro} op1 op2 pflo pfro :
cnraenv_type op1 τenv τin (Either (Rec Closed rll pfl) (Rec Closed rlr pfr)) →
cnraenv_type op2 τenv τin (Rec Closed rlo pfo) →
rec_concat_sort rll rlo = lo →
rec_concat_sort rlr rlo = ro →
cnraenv_type (ANEitherConcat op1 op2) τenv τin (Either (Rec Closed lo pflo) (Rec Closed ro pfro))
| ANTApp {τenv τin τ1 τ2} op2 op1 :
cnraenv_type op1 τenv τin τ1 →
cnraenv_type op2 τenv τ1 τ2 →
cnraenv_type (ANApp op2 op1) τenv τin τ2
| ANTGetConstant {τenv τin τout} s :
tdot τconstants s = Some τout →
cnraenv_type (ANGetConstant s) τenv τin τout
| ANTEnv {τenv τin} :
cnraenv_type ANEnv τenv τin τenv
| ANTAppEnv {τenv τenv' τin τ2} op2 op1 :
cnraenv_type op1 τenv τin τenv' →
cnraenv_type op2 τenv' τin τ2 →
cnraenv_type (ANAppEnv op2 op1) τenv τin τ2
| ANTMapEnv {τenv τin τ₂} op1 :
cnraenv_type op1 τenv τin τ₂ →
cnraenv_type (ANMapEnv op1) (Coll τenv) τin (Coll τ₂).
End typ.
Notation "Op ▷ A >=> B ⊣ C ; E" := (cnraenv_type C Op E A B) (at level 70).
Type lemmas for individual cnraenvebraic expressions
Context {m:basic_model}.
Lemma rmap_typed {τc} {τenv τ₁ τ₂ : rtype} c (op1 : cnraenv) (env:data) (dl : list data) :
(bindings_type c τc) →
(env ▹ τenv) →
(Forall (fun d : data ⇒ data_type d τ₁) dl) →
(op1 ▷ τ₁ >=> τ₂ ⊣ τc; τenv) →
(∀ d : data,
data_type d τ₁ → ∃ x : data, brand_relation_brands ⊢ₑ op1 @ₑ d ⊣ c; env = Some x ∧ x ▹ τ₂) →
∃ x : list data, (rmap (cnraenv_eval brand_relation_brands c op1 env) dl = Some x) ∧ data_type (dcoll x) (Coll τ₂).
Lemma rmap_env_typed {τc} {τenv τ₁ τ₂ : rtype} c (op1 : cnraenv) (x0:data) (dl : list data) :
bindings_type c τc →
(x0 ▹ τ₁) →
(Forall (fun d : data ⇒ data_type d τenv) dl) →
(op1 ▷ τ₁ >=> τ₂ ⊣ τc;τenv) →
(∀ env : data,
data_type env τenv →
∀ d : data,
data_type d τ₁ →
∃ x : data, brand_relation_brands ⊢ₑ op1 @ₑ d ⊣ c;env = Some x ∧ data_type x τ₂) →
∃ x : list data, (rmap (fun env' ⇒ (cnraenv_eval brand_relation_brands c op1 env' x0)) dl = Some x) ∧ data_type (dcoll x) (Coll τ₂).
Lemma recover_rec k d r τ pf:
data_type d r →
` r =
Rec₀ k
(map
(fun x : string × {τ₀ : rtype₀ | wf_rtype₀ τ₀ = true} ⇒
(fst x, ` (snd x))) τ) →
data_type d (Rec k τ pf).
Lemma recover_rec_forall k l r τ pf:
Forall (fun d : data ⇒ data_type d r) l →
` r =
Rec₀ k
(map
(fun x : string × {τ₀ : rtype₀ | wf_rtype₀ τ₀ = true} ⇒
(fst x, ` (snd x))) τ) →
Forall (fun d : data ⇒ data_type d (Rec k τ pf)) l.
Lemma omap_concat_typed_env
(τenv:rtype) (τ₁ τ₂ τ₃: list (string × rtype)) (env:data) (dl2: list data)
(x : list (string × data)) pf1 pf2 pf3:
(data_type env τenv) →
(∀ x : data, In x dl2 → data_type x (Rec Closed τ₂ pf2)) →
rec_concat_sort τ₁ τ₂ = τ₃ →
data_type (drec x) (Rec Closed τ₁ pf1) →
(∃ y : list data,
rmap (fun x1 : data ⇒ orecconcat (drec x) x1) dl2
= Some y ∧ data_type (dcoll y) (Coll (Rec Closed τ₃ pf3))).
Lemma rproduct_typed_env {τenv:rtype} {τ₁ τ₂ τ₃: list (string × rtype)} (env:data) (dl dl0: list data) pf1 pf2 pf3:
data_type env τenv →
Forall (fun d : data ⇒ data_type d (Rec Closed τ₂ pf2)) dl0 →
Forall (fun d : data ⇒ data_type d (Rec Closed τ₁ pf1)) dl →
rec_concat_sort τ₁ τ₂ = τ₃ →
∃ x : list data, (rproduct dl dl0 = Some x) ∧ data_type (dcoll x) (Coll (Rec Closed τ₃ pf3)).
Lemma data_type_concat l1 l2 τ:
data_type (dcoll l1) (Coll τ) →
data_type (dcoll l2) (Coll τ) →
data_type (dcoll (l1 ++ l2)) (Coll τ).
Lemma rmap_concat_typed_env {τc} {τenv:rtype} {τ₁ τ₂ τ₃ : list (string × rtype)} (op1 : cnraenv) c (env:data) (dl: list data) pf1 pf2 pf3:
bindings_type c τc →
env ▹ τenv →
rec_concat_sort τ₁ τ₂ = τ₃ →
Forall (fun d : data ⇒ data_type d (Rec Closed τ₁ pf1)) dl →
(op1 ▷ Rec Closed τ₁ pf1 >=> Coll (Rec Closed τ₂ pf2) ⊣ τc;τenv) →
(∀ d : data,
data_type d (Rec Closed τ₁ pf1) →
∃ x : data,
brand_relation_brands ⊢ₑ op1 @ₑ d ⊣ c;env = Some x ∧ data_type x (Coll (Rec Closed τ₂ pf2))) →
∃ x : list data, (rmap_concat (cnraenv_eval brand_relation_brands c op1 env) dl = Some x) ∧ data_type (dcoll x) (Coll (Rec Closed τ₃ pf3)).
Lemma rmap_concat_typed2_env {τc} {τenv:rtype} {τ₁ τ₂ τ₃ : list (string × rtype)} τin c (op1 : cnraenv) (env:data) y (dl: list data) pf1 pf2 pf3:
bindings_type c τc →
env▹ τenv →
rec_concat_sort τ₁ τ₂ = τ₃ →
Forall (fun d : data ⇒ data_type d (Rec Closed τ₁ pf1)) dl →
(op1 ▷ τin >=> Coll (Rec Closed τ₂ pf2) ⊣ τc;τenv) →
(∀ d : data,
data_type d (Rec Closed τ₁ pf1) →
∃ x : data,
brand_relation_brands ⊢ₑ op1 @ₑ y ⊣ c;env = Some x ∧ data_type x (Coll (Rec Closed τ₂ pf2))) →
∃ x : list data, (rmap_concat (fun z ⇒ brand_relation_brands ⊢ₑ op1@ₑ y ⊣ c;env) dl = Some x) ∧ data_type (dcoll x) (Coll (Rec Closed τ₃ pf3)).
Main typing soundness theorem for NRAEnv
Theorem typed_cnraenv_yields_typed_data {τc} {τenv τin τout} c (env:data) (d:data) (op:cnraenv):
bindings_type c τc →
(env ▹ τenv) → (d ▹ τin) → (op ▷ τin >=> τout ⊣ τc;τenv) →
(∃ x, (brand_relation_brands ⊢ₑ op @ₑ d ⊣ c;env = Some x ∧ (x ▹ τout))).
Corrolaries of the main type soudness theorem
Definition typed_cnraenv_total {τc} {τenv τin τout} (op:cnraenv) (HOpT: op ▷ τin >=> τout ⊣ τc;τenv) c (env:data) (d:data)
(dt_c: bindings_type c τc) :
(env ▹ τenv) →
(d ▹ τin) →
{ x:data | x ▹ τout }.
Definition tcnraenv_eval {τc} {τenv τin τout} (op:cnraenv) (HOpT: op ▷ τin >=> τout ⊣ τc;τenv) c (env:data) (d:data)
(dt_c: bindings_type c τc) :
(env ▹ τenv) → (d ▹ τin) → data.
Auxiliary lemmas specific to some of the NRA expressions used in
the translation
Definition pat_context_type tconst tbind tpid : rtype :=
Rec Closed (("PBIND"%string,tbind) :: ("PCONST"%string,tconst) :: ("PDATA"%string,tpid) :: nil) (eq_refl _).
Lemma ATdot {p s τin τ pf τout}:
p ▷ τin >=> Rec Closed τ pf →
tdot τ s = Some τout →
AUnop (ADot s) p ▷ τin >=> τout.
Lemma ATdot_inv {p s τin τout}:
AUnop (ADot s) p ▷ τin >=> τout →
∃ τ pf k,
p ▷ τin >=> Rec k τ pf ∧
tdot τ s = Some τout.
Lemma ATpat_data τc τ τin :
pat_data ▷ pat_context_type τc τ τin >=> τin.
Lemma ATpat_data_inv' k τc τ τin pf τout:
pat_data ▷ Rec k [("PBIND"%string, τ); ("PCONST"%string, τc); ("PDATA"%string, τin)] pf >=> τout →
τin = τout.
Lemma ATpat_data_inv τc τ τin τout:
pat_data ▷ pat_context_type τc τ τin >=> τout →
τin = τout.
Lemma ATunnest_two (s1 s2:string) (op:NRA.nra) τin τ₁ pf1 τs τrem pf2 :
op ▷ τin >=> (Coll (Rec Closed τ₁ pf1)) →
tdot τ₁ s1 = Some (Coll τs) →
τrem = (rremove (rec_concat_sort τ₁ ((s2,τs)::nil)) s1) →
NRAExt.unnest_two s1 s2 op ▷
τin >=> Coll (Rec Closed τrem pf2).
Lemma ATunnest_two_inv (s1 s2:string) (op:NRA.nra) τin rec :
unnest_two s1 s2 op ▷
τin >=> Coll rec →
∃ τ₁ pf1 τs τrem pf2,
op ▷ τin >=> (Coll (Rec Closed τ₁ pf1)) ∧
tdot τ₁ s1 = Some (Coll τs) ∧
rec = (Rec Closed τrem pf2) ∧
τrem = (rremove (rec_concat_sort τ₁ ((s2,τs)::nil)) s1).
Lemma ATRecEither s τl τr pf1 pf2:
nra_type (ARecEither s) (Either τl τr)
(Either
(Rec Closed ((s,τl)::nil) pf1)
(Rec Closed ((s,τr)::nil) pf2)).
Theorem typed_cnraenv_to_typed_nra {τc} pf {τenv τin τout} (op:cnraenv):
(cnraenv_type τc op τenv τin τout) → (nra_type (nra_of_cnraenv op) (pat_context_type (Rec Closed τc pf) τenv τin) τout).
Lemma fold_pat_context_type (c env d: {τ₀ : rtype₀ | wf_rtype₀ τ₀ = true}) pf :
Rec Closed [("PBIND"%string, env); ("PCONST"%string, c); ("PDATA"%string, d)] pf
= pat_context_type c env d.
Lemma UIP_bool {a b:bool} (pf1 pf2:a = b) : pf1 = pf2.
Lemma typed_cnraenv_to_typed_nra_inv' {k τc pf0 τenv τin τout pf} (op:cnraenv):
nra_type (nra_of_cnraenv op) (Rec k [("PBIND"%string, τenv); ("PCONST"%string, (Rec Closed τc pf0)); ("PDATA"%string, τin)] pf) τout →
cnraenv_type τc op τenv τin τout.
Theorem typed_cnraenv_to_typed_nra_inv {τc} pf {τenv τin τout} (op:cnraenv):
nra_type (nra_of_cnraenv op) (pat_context_type (Rec Closed τc pf) τenv τin) τout →
cnraenv_type τc op τenv τin τout.
Lemma typed_cnraenv_const_sort_f {τc op τenv τin τout} :
cnraenv_type (rec_sort τc) op τenv τin τout →
cnraenv_type τc op τenv τin τout.
Lemma typed_cnraenv_const_sort_b {τc op τenv τin τout} :
cnraenv_type τc op τenv τin τout →
cnraenv_type (rec_sort τc) op τenv τin τout.
Lemma typed_cnraenv_const_sort τc op τenv τin τout :
cnraenv_type (rec_sort τc) op τenv τin τout ↔
cnraenv_type τc op τenv τin τout.
End TcNRAEnv.
Notation "Op ▷ A >=> B ⊣ C ; E" := (cnraenv_type C Op E A B) (at level 70).
Notation "Op @▷ d ⊣ C ; e" := (tcnraenv_eval C Op e d) (at level 70).