Qcert.Translation.TcNNRCtoCAMP
Auxiliary definitions and lemmas
Context {m:basic_model}.
Lemma PTdot {τc} {Γ Γ₁:tbindings} {τ₁ τ₂ p k} (s:string) pf :
NoDup (domain Γ₁) →
RAssoc.lookup equiv_dec Γ₁ s = Some τ₁ →
[τc&Γ] |= p ; τ₁ ~> τ₂ →
[τc&Γ] |= pdot (loop_var s) p ; (Rec k (nnrc_to_pat_env Γ₁) pf) ~> τ₂.
Lemma wf_env_same_domain {env tenv} v :
bindings_type env tenv → (In v (domain env) ↔ In v (domain tenv)).
Lemma loop_var_in_nnrc_to_pat_env {B} {tenv v} :
In v (@domain _ B tenv) ↔
In (loop_var v) (domain (nnrc_to_pat_env tenv)).
Lemma nnrc_to_pat_in {B} Γ v :
In v (@domain _ B Γ) ↔
In (loop_var v) (domain (nnrc_to_pat_env Γ)).
Lemma nnrc_to_pat_nodup {B} Γ :
NoDup (@domain _ B Γ) ↔
NoDup (domain (nnrc_to_pat_env Γ)).
Lemma is_list_sorted_nnrc_to_pat_env_nodup {B} {tenv} :
is_list_sorted ODT_lt_dec (@domain _ B (nnrc_to_pat_env tenv)) = true →
NoDup (domain tenv).
Lemma lookup_incl_perm_nodup {A B} {dec:EqDec A eq} {l1 l2:list (A×B)} :
Permutation l1 l2 →
NoDup (@domain A B l1) →
lookup_incl l1 l2.
Lemma lookup_equiv_perm_nodup {A B} {dec:EqDec A eq} {l1 l2:list (A×B)} :
Permutation l1 l2 →
NoDup (@domain A B l1) →
lookup_equiv l1 l2.
Lemma nnrc_type_context_perm {Γ Γ'} τ n :
Permutation Γ Γ' →
NoDup (domain Γ) →
shadow_free n = true →
(∀ x, In x (domain Γ) → ¬ In x (nnrc_bound_vars n)) →
nnrc_type Γ n τ →
nnrc_type Γ' n τ.
Lemma rec_cons_sort_nnrc_to_pat_env_pullback {A} a b Γ :
NoDup (a :: domain Γ) →
∃ Γ' : list (string×A),
insertion_sort_insert rec_field_lt_dec (loop_var a, b)
(nnrc_to_pat_env Γ) = nnrc_to_pat_env Γ' ∧
Permutation ((a, b) :: Γ) Γ'.
Lemma rec_sort_nnrc_to_pat_env_pullback {A} (Γ:list (string×A)) :
NoDup (domain Γ) →
∃ Γ',
rec_sort (nnrc_to_pat_env Γ) = nnrc_to_pat_env Γ'
∧ Permutation Γ Γ'.
Lemma fresh_bindings_some {A} `{EqDec A eq} (g g1 g2:list (string×A)) :
Some g = merge_bindings g1 g2 ↔
compatible g1 g2 = true ∧
g = rec_concat_sort g1 g2.
Lemma PTdot {τc} {Γ Γ₁:tbindings} {τ₁ τ₂ p k} (s:string) pf :
NoDup (domain Γ₁) →
RAssoc.lookup equiv_dec Γ₁ s = Some τ₁ →
[τc&Γ] |= p ; τ₁ ~> τ₂ →
[τc&Γ] |= pdot (loop_var s) p ; (Rec k (nnrc_to_pat_env Γ₁) pf) ~> τ₂.
Lemma wf_env_same_domain {env tenv} v :
bindings_type env tenv → (In v (domain env) ↔ In v (domain tenv)).
Lemma loop_var_in_nnrc_to_pat_env {B} {tenv v} :
In v (@domain _ B tenv) ↔
In (loop_var v) (domain (nnrc_to_pat_env tenv)).
Lemma nnrc_to_pat_in {B} Γ v :
In v (@domain _ B Γ) ↔
In (loop_var v) (domain (nnrc_to_pat_env Γ)).
Lemma nnrc_to_pat_nodup {B} Γ :
NoDup (@domain _ B Γ) ↔
NoDup (domain (nnrc_to_pat_env Γ)).
Lemma is_list_sorted_nnrc_to_pat_env_nodup {B} {tenv} :
is_list_sorted ODT_lt_dec (@domain _ B (nnrc_to_pat_env tenv)) = true →
NoDup (domain tenv).
Lemma lookup_incl_perm_nodup {A B} {dec:EqDec A eq} {l1 l2:list (A×B)} :
Permutation l1 l2 →
NoDup (@domain A B l1) →
lookup_incl l1 l2.
Lemma lookup_equiv_perm_nodup {A B} {dec:EqDec A eq} {l1 l2:list (A×B)} :
Permutation l1 l2 →
NoDup (@domain A B l1) →
lookup_equiv l1 l2.
Lemma nnrc_type_context_perm {Γ Γ'} τ n :
Permutation Γ Γ' →
NoDup (domain Γ) →
shadow_free n = true →
(∀ x, In x (domain Γ) → ¬ In x (nnrc_bound_vars n)) →
nnrc_type Γ n τ →
nnrc_type Γ' n τ.
Lemma rec_cons_sort_nnrc_to_pat_env_pullback {A} a b Γ :
NoDup (a :: domain Γ) →
∃ Γ' : list (string×A),
insertion_sort_insert rec_field_lt_dec (loop_var a, b)
(nnrc_to_pat_env Γ) = nnrc_to_pat_env Γ' ∧
Permutation ((a, b) :: Γ) Γ'.
Lemma rec_sort_nnrc_to_pat_env_pullback {A} (Γ:list (string×A)) :
NoDup (domain Γ) →
∃ Γ',
rec_sort (nnrc_to_pat_env Γ) = nnrc_to_pat_env Γ'
∧ Permutation Γ Γ'.
Lemma fresh_bindings_some {A} `{EqDec A eq} (g g1 g2:list (string×A)) :
Some g = merge_bindings g1 g2 ↔
compatible g1 g2 = true ∧
g = rec_concat_sort g1 g2.
Proving ``forwards'' type preservation: if the compiled pattern is
well-typed, then the source nnrc is well-typed (with the same type)
Lemma nnrc_to_pat_ns_type_preserve n τc Γ τout :
is_list_sorted ODT_lt_dec (domain (nnrc_to_pat_env Γ)) = true →
shadow_free n = true →
(∀ x, In x (domain Γ) → ¬ In x (nnrc_bound_vars n)) →
nnrc_type Γ n τout →
∀ τ₀,
[τc&(nnrc_to_pat_env Γ)] |= (nnrcToPat_ns n) ; τ₀ ~> τout.
Lemma nnrc_to_pat_ns_top_type_preserve n τc τout :
shadow_free n = true →
nnrc_type nil n τout →
∀ τ₀,
[τc&nil] |= (nnrcToPat_ns n) ; τ₀ ~> τout.
Lemma nnrc_to_pat_type_preserve n τc Γ τout :
is_list_sorted ODT_lt_dec (domain (nnrc_to_pat_env Γ)) = true →
nnrc_type Γ n τout →
∀ τ₀,
[τc&(nnrc_to_pat_env Γ)] |= (nnrcToPat (domain Γ) n) ; τ₀ ~> τout.
Lemma fresh_bindings_cons_loop_var a l p :
fresh_bindings ((loop_var a)::l) p
↔ fresh_bindings l p.
Lemma nnrcToPat_ns_type_ignored_let_binding τc b x xv τ₁ τ₂ n :
nnrcIsCore n →
shadow_free n = true →
RSort.is_list_sorted ODT_lt_dec (domain b) = true →
fresh_bindings (domain b) (nnrcToPat_ns n) →
(∀ x, In x (domain b) → ¬ In x (map loop_var (nnrc_bound_vars n))) →
NoDup (domain b) →
¬ In (let_var x) (let_vars (nnrcToPat_ns n)) →
¬ In (let_var x) (domain b) →
([τc&b] |= (nnrcToPat_ns n) ; τ₁ ~> τ₂) →
[τc&(rec_concat_sort b ((let_var x, xv)::nil))] |= (nnrcToPat_ns n) ; τ₁ ~> τ₂.
Lemma nnrc_to_pat_ns_let_type_equiv n τc Γ τout :
nnrcIsCore n →
is_list_sorted ODT_lt_dec (domain Γ) = true →
fresh_bindings (domain Γ) (nnrcToPat_ns_let n) →
shadow_free n = true →
(∀ x, In x (domain Γ) → ¬ In x (map loop_var (nnrc_bound_vars n))) →
∀ τ₀,
[τc&Γ] |= (nnrcToPat_ns n) ; τ₀ ~> τout →
[τc&Γ] |= (nnrcToPat_ns_let n) ; τ₀ ~> τout.
Lemma fresh_bindings_from_tnnrc {A} e l :
fresh_bindings (@domain _ A (nnrc_to_pat_env e)) l.
Lemma nnrc_to_pat_let_type_preserve n τc Γ τout :
nnrcIsCore n →
is_list_sorted ODT_lt_dec (domain (nnrc_to_pat_env Γ)) = true →
nnrc_type Γ n τout →
∀ τ₀,
[τc&(nnrc_to_pat_env Γ)] |= (nnrcToPat_let (domain Γ) n) ; τ₀ ~> τout.
Lemma nnrc_to_pat_ns_let_top_type_preserve n τc τout :
nnrcIsCore n →
shadow_free n = true →
nnrc_type nil n τout →
∀ τ₀,
[τc&nil] |= (nnrcToPat_ns_let n) ; τ₀ ~> τout.
is_list_sorted ODT_lt_dec (domain (nnrc_to_pat_env Γ)) = true →
shadow_free n = true →
(∀ x, In x (domain Γ) → ¬ In x (nnrc_bound_vars n)) →
nnrc_type Γ n τout →
∀ τ₀,
[τc&(nnrc_to_pat_env Γ)] |= (nnrcToPat_ns n) ; τ₀ ~> τout.
Lemma nnrc_to_pat_ns_top_type_preserve n τc τout :
shadow_free n = true →
nnrc_type nil n τout →
∀ τ₀,
[τc&nil] |= (nnrcToPat_ns n) ; τ₀ ~> τout.
Lemma nnrc_to_pat_type_preserve n τc Γ τout :
is_list_sorted ODT_lt_dec (domain (nnrc_to_pat_env Γ)) = true →
nnrc_type Γ n τout →
∀ τ₀,
[τc&(nnrc_to_pat_env Γ)] |= (nnrcToPat (domain Γ) n) ; τ₀ ~> τout.
Lemma fresh_bindings_cons_loop_var a l p :
fresh_bindings ((loop_var a)::l) p
↔ fresh_bindings l p.
Lemma nnrcToPat_ns_type_ignored_let_binding τc b x xv τ₁ τ₂ n :
nnrcIsCore n →
shadow_free n = true →
RSort.is_list_sorted ODT_lt_dec (domain b) = true →
fresh_bindings (domain b) (nnrcToPat_ns n) →
(∀ x, In x (domain b) → ¬ In x (map loop_var (nnrc_bound_vars n))) →
NoDup (domain b) →
¬ In (let_var x) (let_vars (nnrcToPat_ns n)) →
¬ In (let_var x) (domain b) →
([τc&b] |= (nnrcToPat_ns n) ; τ₁ ~> τ₂) →
[τc&(rec_concat_sort b ((let_var x, xv)::nil))] |= (nnrcToPat_ns n) ; τ₁ ~> τ₂.
Lemma nnrc_to_pat_ns_let_type_equiv n τc Γ τout :
nnrcIsCore n →
is_list_sorted ODT_lt_dec (domain Γ) = true →
fresh_bindings (domain Γ) (nnrcToPat_ns_let n) →
shadow_free n = true →
(∀ x, In x (domain Γ) → ¬ In x (map loop_var (nnrc_bound_vars n))) →
∀ τ₀,
[τc&Γ] |= (nnrcToPat_ns n) ; τ₀ ~> τout →
[τc&Γ] |= (nnrcToPat_ns_let n) ; τ₀ ~> τout.
Lemma fresh_bindings_from_tnnrc {A} e l :
fresh_bindings (@domain _ A (nnrc_to_pat_env e)) l.
Lemma nnrc_to_pat_let_type_preserve n τc Γ τout :
nnrcIsCore n →
is_list_sorted ODT_lt_dec (domain (nnrc_to_pat_env Γ)) = true →
nnrc_type Γ n τout →
∀ τ₀,
[τc&(nnrc_to_pat_env Γ)] |= (nnrcToPat_let (domain Γ) n) ; τ₀ ~> τout.
Lemma nnrc_to_pat_ns_let_top_type_preserve n τc τout :
nnrcIsCore n →
shadow_free n = true →
nnrc_type nil n τout →
∀ τ₀,
[τc&nil] |= (nnrcToPat_ns_let n) ; τ₀ ~> τout.
Proving ``backwards'' type preservation: if the compiled pattern is
well-typed, then the source nnrc is well-typed (with the same type)
Lemma nnrc_to_pat_ns_type_preserve_back n τc Γ τout :
nnrcIsCore n →
is_list_sorted ODT_lt_dec (domain (nnrc_to_pat_env Γ)) = true →
shadow_free n = true →
(∀ x, In x (domain Γ) → ¬ In x (nnrc_bound_vars n)) →
∀ τ₀,
[τc&(nnrc_to_pat_env Γ)] |= (nnrcToPat_ns n) ; τ₀ ~> τout →
nnrc_type Γ n τout.
Lemma nnrc_to_pat_ns_top_type_preserve_back n τc τout :
nnrcIsCore n →
shadow_free n = true →
∀ τ₀,
[τc&nil] |= (nnrcToPat_ns n) ; τ₀ ~> τout →
nnrc_type nil n τout.
Lemma PTmapall_let τc {Γ : tbindings} {τ₁ τ₂ : rtype} {p : pat} :
NoDup (domain Γ) →
fresh_bindings (domain Γ) (mapall_let p) →
([τc&Γ] |= p; τ₁ ~> τ₂) → [τc&Γ] |= mapall_let p; Coll τ₁ ~> Coll τ₂.
Lemma PTmapall_let_inv τc {Γ : tbindings} {τ₁ τ₂ : rtype} {p : pat} :
RSort.is_list_sorted ODT_lt_dec (domain Γ) = true →
fresh_bindings (domain Γ) (mapall_let p) →
[τc&Γ] |= mapall_let p; τ₁ ~> τ₂ →
∃ τ₁' τ₂',
τ₁ = Coll τ₁' ∧
τ₂ = Coll τ₂' ∧
([τc&Γ] |= p; τ₁' ~> τ₂').
Lemma nnrcToPat_ns_type_weaken_let_binding τc b x xv τ₁ τ₂ n :
nnrcIsCore n →
shadow_free n = true →
RSort.is_list_sorted ODT_lt_dec (domain b) = true →
fresh_bindings (domain b) (nnrcToPat_ns n) →
(∀ x, In x (domain b) → ¬ In x (map loop_var (nnrc_bound_vars n))) →
NoDup (domain b) →
¬ In (let_var x) (let_vars (nnrcToPat_ns n)) →
¬ In (let_var x) (domain b) →
[τc&(rec_concat_sort b
((let_var x, xv)::nil))] |= (nnrcToPat_ns n) ; τ₁ ~> τ₂ →
[τc&b] |= (nnrcToPat_ns n) ; τ₁ ~> τ₂.
Lemma nnrc_to_pat_ns_let_type_equiv_back n τc Γ τout :
nnrcIsCore n →
is_list_sorted ODT_lt_dec (domain Γ) = true →
fresh_bindings (domain Γ) (nnrcToPat_ns_let n) →
shadow_free n = true →
(∀ x, In x (domain Γ) → ¬ In x (map loop_var (nnrc_bound_vars n))) →
∀ τ₀,
[τc&Γ] |= (nnrcToPat_ns_let n) ; τ₀ ~> τout →
[τc&Γ] |= (nnrcToPat_ns n) ; τ₀ ~> τout.
Lemma nnrc_to_pat_let_type_preserve_back n τc Γ τout :
nnrcIsCore n →
is_list_sorted ODT_lt_dec (domain (nnrc_to_pat_env Γ)) = true →
∀ τ₀,
[τc&(nnrc_to_pat_env Γ)] |= (nnrcToPat_let (domain Γ) n) ; τ₀ ~> τout →
nnrc_type Γ n τout.
Lemma nnrc_to_pat_ns_let_top_type_preserve_back n τc τout :
nnrcIsCore n →
shadow_free n = true →
∀ τ₀,
[τc&nil] |= (nnrcToPat_ns_let n) ; τ₀ ~> τout →
nnrc_type nil n τout.
Theorem 7.4, NNRC<->CAMP.
Final iff Theorem of type preservation for the translation
from NNRC back to Patterns