# HG changeset patch # User urbanc # Date 1136903011 -3600 # Node ID da46244359659d61337ac3594b0300577664680b # Parent f0acb66858b4703820e8336f3044953b8cd33188 tuned diff -r f0acb66858b4 -r da4624435965 src/HOL/Nominal/Examples/Fsub.thy --- a/src/HOL/Nominal/Examples/Fsub.thy Tue Jan 10 02:32:10 2006 +0100 +++ b/src/HOL/Nominal/Examples/Fsub.thy Tue Jan 10 15:23:31 2006 +0100 @@ -76,9 +76,9 @@ text {* Typing contexts are represented as lists "growing" on the left; we thereby deviating from the convention in the POPLmark-paper. The lists contain - pairs of type-variables and types. *} + pairs of type-variables and types (this is sufficient for the Part 1A). *} -text {* In order to state valitity-conditions for typing-contexts, the notion of +text {* In order to state validity-conditions for typing-contexts, the notion of a @{text "domain"} of a typing-context is handy. *} consts @@ -195,14 +195,6 @@ shows "\ \ ok" using a by (induct \, auto dest: validE) -lemma closed_in_fresh: - fixes X::"tyvrs" - assumes a: "S closed_in \" - and b: "X\(domain \)" - and c: "\ \ ok" - shows "X\S" -using a b c by (force simp add: fresh_def domain_supp closed_in_def) - lemma replace_type: assumes a: "\ (\@(X,T)#\) ok" and b: "S closed_in \" @@ -236,11 +228,11 @@ ultimately show "T=S" by auto qed -section {* Size and Capture-Avoiding Substitutiuon for Types *} +section {* Size and Capture-Avoiding Substitution for Types *} text {* In the current version of the nominal datatype-package even simple functions (such as size of types and capture-avoiding substitution) can - only be defined manually via some labourious proof constructions. Therefore + only be defined manually via some laborious proof constructions. Therefore we sill just assume them here. *} consts size_ty :: "ty \ nat" @@ -269,6 +261,10 @@ section {* Subtyping-Relation *} +text {* The subtype relation follows what is written in the POPLmark-paper, except + for the premises dealing with well-formed contexts and the freshness constraint + @{term "X\\"} in the rule @{text "S_Forall"}. *} + consts subtype_of :: "(ty_context \ ty \ ty) set" syntax @@ -327,6 +323,10 @@ ultimately show "X\S \ X\T" by (force simp add: supp_prod fresh_def) qed +text {* Two silly lemmas that are necessary to show that @{text "subtype_of"} is + equivariant. They are necessary at the moment until we have a tactic that shows + equivariance automatically. *} + lemma silly_eqvt1: fixes X::"'a::pt_tyvrs" and S::"'b::pt_tyvrs" @@ -355,16 +355,27 @@ apply(force intro!: S_Forall simp add: fresh_prod fresh_eqvt) done +text {* The most painful part of the subtyping definition is the strengthening of the + induction principle. The induction principle that comes for free with the definition of + @{term "subtype_of"} requires to prove the @{text "S_Forall"}-case for all binders + @{text "X"}. This will require some renaming-manoeuvres in the reasoning. To avoid this, + we strengthening the induction-principle so that we only have to establish + the @{text "S_Forall"}-case for fresh binders @{text "X"}. The property that allows + us to strengthen the induction-principle is that the relation @{text "subtype_of"} is + equivariant. *} + lemma subtype_of_induct[consumes 1, case_names S_Top S_Var S_Refl S_Arrow S_Forall]: fixes P :: "'a::fs_tyvrs\ty_context \ ty \ ty \bool" assumes a: "\ \ S <: T" and a1: "\\ S x. \\ \ ok; S closed_in \\ \ P x \ S Top" and a2: "\\ X S T x. \(X,S)\set \; \ \ S <: T; \z. P z \ S T\ \ P x \ (Tvar X) T" and a3: "\\ X x. \\ \ ok; X\domain \\ \ P x \ (Tvar X) (Tvar X)" - and a4: "\\ S\<^isub>1 S\<^isub>2 T\<^isub>1 T\<^isub>2 x. \\ \ T\<^isub>1 <: S\<^isub>1; \z. P z \ T\<^isub>1 S\<^isub>1; \ \ S\<^isub>2 <: T\<^isub>2; \z. P z \ S\<^isub>2 T\<^isub>2\ + and a4: "\\ S\<^isub>1 S\<^isub>2 T\<^isub>1 T\<^isub>2 x. + \\ \ T\<^isub>1 <: S\<^isub>1; \z. P z \ T\<^isub>1 S\<^isub>1; \ \ S\<^isub>2 <: T\<^isub>2; \z. P z \ S\<^isub>2 T\<^isub>2\ \ P x \ (S\<^isub>1 \ S\<^isub>2) (T\<^isub>1 \ T\<^isub>2)" and a5: "\\ X S\<^isub>1 S\<^isub>2 T\<^isub>1 T\<^isub>2 x. - \X\x; X\(\,S\<^isub>1,T\<^isub>1); \ \ T\<^isub>1 <: S\<^isub>1; \z. P z \ T\<^isub>1 S\<^isub>1; ((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2; \z. P z ((X,T\<^isub>1)#\) S\<^isub>2 T\<^isub>2\ + \X\x; X\(\,S\<^isub>1,T\<^isub>1); \ \ T\<^isub>1 <: S\<^isub>1; \z. P z \ T\<^isub>1 S\<^isub>1; + ((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2; \z. P z ((X,T\<^isub>1)#\) S\<^isub>2 T\<^isub>2\ \ P x \ (\[X<:S\<^isub>1].S\<^isub>2) (\[X<:T\<^isub>1].T\<^isub>2)" shows "P x \ S T" proof - @@ -483,27 +494,28 @@ apply(auto simp add: ty.supp abs_supp closed_in_def supp_atm) --{* Too bad that this instantiation cannot be found automatically by \isakeyword{auto}; \isakeyword{blast} would find it if we had not used - the definition @{text "closed_in_def"}. *} + an explicit definition for @{text "closed_in_def"}. *} apply(drule_tac x="(tyvrs, ty2)#\" in meta_spec) apply(force simp add: closed_in_def fresh_domain) done -text {* Inversion lemmas *} +text {* Some inversion lemmas: *} + lemma S_TopE: assumes a: "\ \ Top <: T" shows "T = Top" using a by (cases, auto) lemma S_ArrowE_left: - assumes a: "\ \ S1 \ S2 <: T" - shows "T = Top \ (\T1 T2. T = T1 \ T2 \ \ \ T1 <: S1 \ \ \ S2 <: T2)" + assumes a: "\ \ S\<^isub>1 \ S\<^isub>2 <: T" + shows "T = Top \ (\T\<^isub>1 T\<^isub>2. T = T\<^isub>1 \ T\<^isub>2 \ \ \ T\<^isub>1 <: S\<^isub>1 \ \ \ S\<^isub>2 <: T\<^isub>2)" using a by (cases, auto simp add: ty.inject) lemma S_ForallE_left: - shows "\\ \ \[X<:S1].S2 <: T; X\\; X\S1\ - \ T = Top \ (\T1 T2. T = \[X<:T1].T2 \ \ \ T1 <: S1 \ ((X,T1)#\) \ S2 <: T2)" + shows "\\ \ \[X<:S\<^isub>1].S\<^isub>2 <: T; X\\; X\S\<^isub>1\ + \ T = Top \ (\T\<^isub>1 T\<^isub>2. T = \[X<:T\<^isub>1].T\<^isub>2 \ \ \ T\<^isub>1 <: S\<^isub>1 \ ((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2)" apply(frule subtype_implies_ok) - apply(ind_cases "\ \ \[X<:S1].S2 <: T") + apply(ind_cases "\ \ \[X<:S\<^isub>1].S\<^isub>2 <: T") apply(auto simp add: ty.inject alpha) apply(rule_tac x="[(X,Xa)]\T\<^isub>2" in exI) (* term *) @@ -535,78 +547,11 @@ apply(simp add: pt_fresh_fresh[OF pt_tyvrs_inst, OF at_tyvrs_inst]) done -section {* Type Substitution *} - -lemma subst_ty_fresh: - fixes X :: "tyvrs" - assumes a: "X\(T,P)" - shows "X\T[Y:=P]\<^isub>t\<^isub>y" - using a - apply (nominal_induct T avoiding : T Y P rule: ty.induct_unsafe) - apply (auto simp add: fresh_prod abs_fresh) - done - -lemma subst_ctxt_fresh: - fixes X::"tyvrs" - assumes a: "X\(\,P)" - shows "X\\[Y:=P]\<^isub>t\<^isub>y\<^isub>c" - using a - apply (induct \) - apply (auto intro: subst_ty_fresh simp add: fresh_prod fresh_list_cons) - done - -(* -lemma subst_ctxt_closed: - shows "subst_ty b X P closed_in (subst_ctxt \ X P @ \)" - +section {* Weakening *} -lemma substitution_ok: - shows "\ (\@(X,Q)#\) ok \ \ \ P <: Q \ \ ((subst_ctxt \ X P)@\) ok" - apply (induct \) - apply (auto dest: validE) - apply (rule v2) - apply assumption - apply (drule validE) - apply (auto simp add: fresh_list_append) - apply (rule subst_ctxt_fresh) - apply (simp add: fresh_prod) - apply (drule_tac X = "a" in subtype_implies_fresh) - apply (simp add: fresh_list_cons) - apply (simp add: fresh_prod) - apply (simp add: fresh_list_cons) - apply (drule validE) - -done -*) - -(* note: What should nominal induct do if the context is compound? *) -(* -lemma type_substitution: - assumes a0: "(\@(X,Q)#\) \ S <: T" - shows "\ (\@(X,Q)#\) ok \ \ \ P <: Q - \ ((subst_ctxt \ X P)@\) \ (subst_ty S X P) <: (subst_ty T X P)" - using a0 - thm subtype_of_induct - apply(rule subtype_of_induct[of "\@(X,Q)#\" "S" "T" _ "P"]) - apply(auto) - apply(rule S_Top) - defer - defer - defer - apply(rule S_Var) - defer - defer - defer - defer - apply(rule S_Refl) - defer - defer - - -apply (nominal_induct \ X Q \ S T rule: subtype_of_induct) -*) - -section {* Weakening *} +text {* In order to prove weakening we introduce the notion of a type-context extending + another. This generalization seems to make the proof for weakening to be + smoother than if we had strictly adhered to the version in the POPLmark-paper. *} constdefs extends :: "ty_context \ ty_context \ bool" ("_ extends _" [100,100] 100) @@ -690,7 +635,7 @@ text {* In fact all "non-binding" cases can be solved automatically: *} -lemma weakening_semiautomated: +lemma weakening_more_automated: assumes a: "\ \ S <: T" and b: "\ \ ok" and c: "\ extends \" @@ -708,7 +653,7 @@ have ext: "\ extends \" by fact have "T\<^isub>1 closed_in \" using ext closed\<^isub>T\<^isub>1 by (simp only: extends_closed) hence "\ ((X,T\<^isub>1)#\) ok" using fresh_domain ok by force - moreover + moreover have "((X,T\<^isub>1)#\) extends ((X,T\<^isub>1)#\)" using ext by (force simp add: extends_def) ultimately have "((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2" using ih\<^isub>2 by simp moreover @@ -716,6 +661,9 @@ ultimately show "\ \ \[X<:S\<^isub>1].S\<^isub>2 <: \[X<:T\<^isub>1].T\<^isub>2" using ok by (force intro: S_Forall) qed (blast intro: extends_closed extends_memb dest: extends_domain)+ + +section {* Transitivity and Narrowing *} + text {* Next we prove the transitivity and narrowing for the subtyping relation. The POPLmark-paper says the following: @@ -738,7 +686,7 @@ @{thm measure_induct_rule[of "size_ty",no_vars]} \end{center} -It says in English: in order to show a property @{term "P a"} for all @{term "a"}, +That means in order to show a property @{term "P a"} for all @{term "a"}, it requires to prove that for all @{term x} @{term "P x"} holds using the assumption that for all @{term y} whose size is strictly smaller than that of @{term x} the property @{term "P y"} holds. *} @@ -804,7 +752,7 @@ @{term Q\<^isub>1} and @{term Q\<^isub>2} is smaller than that of @{term Q}; so we can apply the outer induction hypotheses for @{term Q\<^isub>1} and @{term Q\<^isub>2}. We also have the sub-derivations @{term "\\Q\<^isub>1<:S\<^isub>1"} and @{term "\\S\<^isub>2<:Q\<^isub>2"}. - The right-hand derivation is @{term "\ \ Q\<^isub>1 \ Q\<^isub>2 <: T"}. There exists types + The right-hand derivation is @{term "\ \ Q\<^isub>1 \ Q\<^isub>2 <: T"}. There exist types @{text "T\<^isub>1,T\<^isub>2"} such that @{term "T=Top \ T=T\<^isub>1\T\<^isub>2"}. The @{term "Top"}-case is straightforward once we know @{term "(S\<^isub>1 \ S\<^isub>2) closed_in \"} and @{term "\ \ ok"}. In the other case we have the sub-derivations @{term "\\T\<^isub>1<:Q\<^isub>1"} and @{term "\\Q\<^isub>2<:T\<^isub>2"}. @@ -854,12 +802,13 @@ and @{term "X\Q\<^isub>1"} there exists types @{text "T\<^isub>1,T\<^isub>2"} such that @{text "T=Top \ T=\[X<:T\<^isub>1].T\<^isub>2"}. The @{term "Top"}-case is straightforward once we know @{text "(\[X<:S\<^isub>1].S\<^isub>2) closed_in \"} and @{term "\ \ ok"}. In the other case we have - the sub-derivations @{term "\\T\<^isub>1<:Q\<^isub>1"}. @{term "((X,T\<^isub>1)#\)\Q\<^isub>2<:T\<^isub>2"}. Using the outer + the sub-derivations @{term "\\T\<^isub>1<:Q\<^isub>1"} and @{term "((X,T\<^isub>1)#\)\Q\<^isub>2<:T\<^isub>2"}. Using the outer induction hypothesis for transitivity we can derive @{term "\\T\<^isub>1<:S\<^isub>1"}. From the outer - induction for narrowing we get @{term "((X,T\<^isub>1)#\) \ S\<^isub>2 <: Q\<^isub>2"} and then using induction - again @{term "((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2"}. By rule @{text "S_Forall"} and the freshness - condition @{term "X\\"} follows @{text "\ \ \[X<:S\<^isub>1].S\<^isub>2 <: \[X<:T\<^isub>1].T\<^isub>2"}.which is - @{text "\ \ \[X<:S\<^isub>1].S\<^isub>2 <: T\<^isub>"}.\end{minipage}*} + induction for narrowing we get @{term "((X,T\<^isub>1)#\) \ S\<^isub>2 <: Q\<^isub>2"} and then using again + induction for transitivity we obtain @{term "((X,T\<^isub>1)#\) \ S\<^isub>2 <: T\<^isub>2"}. By rule + @{text "S_Forall"} and the freshness condition @{term "X\\"} follows + @{text "\ \ \[X<:S\<^isub>1].S\<^isub>2 <: \[X<:T\<^isub>1].T\<^isub>2"}.which is @{text "\ \ \[X<:S\<^isub>1].S\<^isub>2 <: T\<^isub>"}. + \end{minipage}*} hence rh_drv: "\ \ \[X<:Q\<^isub>1].Q\<^isub>2 <: T" by simp have lh_drv_prm\<^isub>1: "\ \ Q\<^isub>1 <: S\<^isub>1" by fact have lh_drv_prm\<^isub>2: "((X,Q\<^isub>1)#\) \ S\<^isub>2 <: Q\<^isub>2" by fact @@ -925,17 +874,17 @@ next case (S_Var _ Y S N \ \ X) --{* \begin{minipage}[t]{0.9\textwidth} - In this case the left-hand derivation is @{term "(\@[(X,Q)]@\) \ Tvar Y <: N"}. We therefore + In this case the left-hand derivation is @{term "(\@[(X,Q)]@\) \ Tvar Y <: N"} and + by inner induction hypothesis we have @{term "(\@[(X,P)]@\) \ S <: N"}. We therefore know that the contexts @{term "\@[(X,Q)]@\"} and @{term "\@[(X,P)]@\"} are ok, and that - @{term "(Y,S)"} is in @{term "\@[(X,Q)]@\"}. By inner induction hypothesis we have - @{term "(\@[(X,P)]@\) \ S <: N"}. We need to show that @{term "(\@[(X,P)]@\) \ Tvar Y <: N"} - holds. In case @{term "X\Y"} we know that @{term "(Y,S)"} is in @{term "\@[(X,P)]@\"} and - can use the inner induction hypothesis and rule @{text "S_Var"} to conclude. In case - @{term "X=Y"} we can infer that @{term "S=Q"}; moreover we have that - @{term "(\@[(X,P)]@\) extends \"} and therefore by @{text "weakening"} that - @{term "(\@[(X,P)]@\) \ P <: Q"} holds. By transitivity we obtain then - @{term "(\@[(X,P)]@\) \ P <: N"} and can conclude by applying rule @{text "S_Var"}. - \end{minipage}*} + @{term "(Y,S)"} is in @{term "\@[(X,Q)]@\"}. We need to show that + @{term "(\@[(X,P)]@\) \ Tvar Y <: N"} holds. In case @{term "X\Y"} we know that + @{term "(Y,S)"} is in @{term "\@[(X,P)]@\"} and can use the inner induction hypothesis + and rule @{text "S_Var"} to conclude. In case @{term "X=Y"} we can infer that + @{term "S=Q"}; moreover we have that @{term "(\@[(X,P)]@\) extends \"} and therefore + by @{text "weakening"} that @{term "(\@[(X,P)]@\) \ P <: Q"} holds. By transitivity we + obtain then @{term "(\@[(X,P)]@\) \ P <: N"} and can conclude by applying rule + @{text "S_Var"}.\end{minipage}*} hence IH_inner: "(\@[(X,P)]@\) \ S <: N" and lh_drv_prm: "(Y,S) \ set (\@[(X,Q)]@\)" and rh_drv: "\ \ P<:Q" @@ -964,7 +913,7 @@ case (S_Refl _ Y \ \ X) --{* \begin{minipage}[t]{0.9\textwidth} In this case the left-hand derivation is @{term "(\@[(X,Q)]@\) \ Tvar Y <: Tvar Y"} and we - therefore know that @{term "\@[(X,Q)]@\"} is ok and thad @{term "Y"} is in + therefore know that @{term "\@[(X,Q)]@\"} is ok and that @{term "Y"} is in the domain of @{term "\@[(X,Q)]@\"}. We therefore know that @{term "\@[(X,P)]@\"} is ok and that @{term Y} is in the domain of @{term "\@[(X,P)]@\"}. We can conclude by applying rule @{text "S_Refl"}.\end{minipage}*} @@ -985,7 +934,7 @@ next case (S_Forall _ Y S\<^isub>1 S\<^isub>2 T\<^isub>1 T\<^isub>2 \ \ X) --{* \begin{minipage}[t]{0.9\textwidth} - In this case teh left-hand derivation is @{text "(\@[(X,Q)]@\) \ \[Y<:S\<^isub>1].S\<^isub>2 <: \[Y<:T\<^isub>1].T\<^isub>2"} + In this case the left-hand derivation is @{text "(\@[(X,Q)]@\) \ \[Y<:S\<^isub>1].S\<^isub>2 <: \[Y<:T\<^isub>1].T\<^isub>2"} and therfore we know that the binder @{term Y} is fresh for @{term "\@[(X,Q)]@\"}. By the inner induction hypothesis we have that @{term "(\@[(X,P)]@\) \ T\<^isub>1 <: S\<^isub>1"} and @{term "((Y,T\<^isub>1)#\@[(X,P)]@\) \ S\<^isub>2 <: T\<^isub>2"}. Since @{term P} is a subtype of @{term Q} @@ -1005,5 +954,4 @@ } qed - end \ No newline at end of file