# HG changeset patch # User urbanc # Date 1133794519 -3600 # Node ID 4dd468ccfdf787d0a4ebd6cbe85786f6eac8e537 # Parent b9d0bd76286c091c020f7c8d940b58a0f60189af transitivity should be now in a reasonable state. But Markus has to have a look at some of the advanced features. diff -r b9d0bd76286c -r 4dd468ccfdf7 src/HOL/Nominal/Examples/Fsub.thy --- a/src/HOL/Nominal/Examples/Fsub.thy Mon Dec 05 10:33:30 2005 +0100 +++ b/src/HOL/Nominal/Examples/Fsub.thy Mon Dec 05 15:55:19 2005 +0100 @@ -258,7 +258,7 @@ case S_All thus ?case by (auto simp add: closed_in_def ty.supp abs_supp) qed -text {* completely automated proof *} +text {* a completely automated proof *} lemma subtype_implies_closed: assumes a: "\ \ S <: T" shows "S closed_in \ \ T closed_in \" @@ -422,24 +422,24 @@ section {* Two proofs for reflexivity of subtyping *} lemma subtype_reflexivity: - shows "\ \ ok \ T closed_in \ \ \ \ T <: T" -proof(nominal_induct T fresh: \ rule: ty.induct_unsafe) + assumes a: "\ \ ok" + and b: "T closed_in \" + shows "\ \ T <: T" +using a b +proof(nominal_induct T avoiding: \ rule: ty.induct_unsafe) case (TAll X T1 T2) - have i1: "\\. \ \ ok \ T1 closed_in \ \ \ \ T1 <: T1" by fact - have i2: "\\. \ \ ok \ T2 closed_in \ \ \ \ T2 <: T2" by fact + have i1: "\\. \ \ ok \ T1 closed_in \ \ \ \ T1 <: T1" by fact + have i2: "\\. \ \ ok \ T2 closed_in \ \ \ \ T2 <: T2" by fact have f: "X\\" by fact - show "\ \ ok \ (\[X<:T2].T1) closed_in \ \ \ \ \[X<:T2].T1 <: \[X<:T2].T1" - proof (intro strip) - assume "(\[X<:T2].T1) closed_in \" - hence b1: "T2 closed_in \" and b2: "T1 closed_in ((X,T2)#\)" + have "(\[X<:T2].T1) closed_in \" by fact + hence b1: "T2 closed_in \" and b2: "T1 closed_in ((X,T2)#\)" by (auto simp add: closed_in_def ty.supp abs_supp) - assume c1: "\ \ ok" - hence c2: "\ ((X,T2)#\) ok" using b1 f by force - have "\ \ T2 <: T2" using i2 b1 c1 by simp - moreover - have "((X,T2)#\) \ T1 <: T1" using i1 b2 c2 by simp - ultimately show "\ \ \[X<:T2].T1 <: \[X<:T2].T1" using f by force - qed + have c1: "\ \ ok" by fact + hence c2: "\ ((X,T2)#\) ok" using b1 f by force + have "\ \ T2 <: T2" using i2 b1 c1 by simp + moreover + have "((X,T2)#\) \ T1 <: T1" using i1 b2 c2 by simp + ultimately show "\ \ \[X<:T2].T1 <: \[X<:T2].T1" using f by force qed (auto simp add: closed_in_def ty.supp supp_atm) lemma subtype_reflexivity: @@ -447,7 +447,7 @@ and b: "T closed_in \" shows "\ \ T <: T" using a b -apply(nominal_induct T fresh: \ rule: ty.induct_unsafe) +apply(nominal_induct T avoiding: \ rule: ty.induct_unsafe) apply(auto simp add: ty.supp abs_supp closed_in_def supp_atm) (* too bad that this cannot be found automatically *) apply(drule_tac x="(tyvrs, ty2)#\" in meta_spec) @@ -508,7 +508,7 @@ fixes P :: "ty" and X :: "tyvrs" shows "X\(T,P) \ X\(subst_ty T Y P)" - apply (nominal_induct T fresh: T Y P rule: ty.induct_unsafe) + apply (nominal_induct T avoiding : T Y P rule: ty.induct_unsafe) apply (auto simp add: fresh_prod abs_fresh) done @@ -593,75 +593,67 @@ by (auto dest: extends_domain simp add: closed_in_def) lemma weakening: - assumes a1: "\ \ S <: T" - shows "\ \ ok \ \ extends \ \ \ \ S <: T" - using a1 -proof (nominal_induct \ S T fresh: \ rule: subtype_of_rel_induct) + assumes a: "\ \ S <: T" + and b: "\ \ ok" + and c: "\ extends \" + shows "\ \ S <: T" + using a b c +proof (nominal_induct \ S T avoiding: \ rule: subtype_of_rel_induct) case (S_Top \ S) have lh_drv_prem: "S closed_in \" by fact - show "\ \ ok \ \ extends \ \ \ \ S <: Top" - proof (intro strip) - assume "\ \ ok" - moreover - assume "\ extends \" - hence "S closed_in \" using lh_drv_prem by (rule_tac extends_closed) - ultimately show "\ \ S <: Top" by force - qed + have "\ \ ok" by fact + moreover + have "\ extends \" by fact + hence "S closed_in \" using lh_drv_prem by (rule_tac extends_closed) + ultimately show "\ \ S <: Top" by force next case (S_Var \ X S T) have lh_drv_prem: "(X,S) \ set \" by fact - have ih: "\\. \ \ ok \ \ extends \ \ \ \ S <: T" by fact - show "\ \ ok \ \ extends \ \ \ \ TyVar X <: T" - proof (intro strip) - assume ok: "\ \ ok" - and extends: "\ extends \" - have "(X,S) \ set \" using lh_drv_prem extends by (simp add: extends_def) - moreover - have "\ \ S <: T" using ok extends ih by simp - ultimately show "\ \ TyVar X <: T" using ok by force - qed + have ih: "\\. \ \ ok \ \ extends \ \ \ \ S <: T" by fact + have ok: "\ \ ok" by fact + have extends: "\ extends \" by fact + have "(X,S) \ set \" using lh_drv_prem extends by (simp add: extends_def) + moreover + have "\ \ S <: T" using ok extends ih by simp + ultimately show "\ \ TyVar X <: T" using ok by force next case (S_Refl \ X) have lh_drv_prem: "X \ domain \" by fact - show ?case - proof (intro strip) - assume "\ \ ok" - moreover - assume "\ extends \" - hence "X \ domain \" using lh_drv_prem by (force dest: extends_domain) - ultimately show "\ \ TyVar X <: TyVar X" by force - qed + have "\ \ ok" by fact + moreover + have "\ extends \" by fact + hence "X \ domain \" using lh_drv_prem by (force dest: extends_domain) + ultimately show "\ \ TyVar X <: TyVar X" by force next case S_Arrow thus ?case by force next case (S_All \ X S1 S2 T1 T2) have fresh: "X\\" by fact - have ih1: "\\. \ \ ok \ \ extends \ \ \ \ T1 <: S1" by fact - have ih2: "\\. \ \ ok \ \ extends ((X,T1)#\) \ \ \ S2 <: T2" by fact + have ih1: "\\. \ \ ok \ \ extends \ \ \ \ T1 <: S1" by fact + have ih2: "\\. \ \ ok \ \ extends ((X,T1)#\) \ \ \ S2 <: T2" by fact have lh_drv_prem: "\ \ T1 <: S1" by fact hence b5: "T1 closed_in \" by (simp add: subtype_implies_closed) - show "\ \ ok \ \ extends \ \ \ \ \ [X<:S1].S2 <: \ [X<:T1].T2" - proof (intro strip) - assume ok: "\ \ ok" - and extends: "\ extends \" - have "T1 closed_in \" using extends b5 by (simp only: extends_closed) - hence "\ ((X,T1)#\) ok" using fresh ok by force - moreover - have "((X,T1)#\) extends ((X,T1)#\)" using extends by (force simp add: extends_def) - ultimately have "((X,T1)#\) \ S2 <: T2" using ih2 by simp - moreover - have "\ \ T1 <: S1" using ok extends ih1 by simp - ultimately show "\ \ \ [X<:S1].S2 <: \ [X<:T1].T2" using ok by (force intro: S_All) - qed + have ok: "\ \ ok" by fact + have extends: "\ extends \" by fact + have "T1 closed_in \" using extends b5 by (simp only: extends_closed) + hence "\ ((X,T1)#\) ok" using fresh ok by force + moreover + have "((X,T1)#\) extends ((X,T1)#\)" using extends by (force simp add: extends_def) + ultimately have "((X,T1)#\) \ S2 <: T2" using ih2 by simp + moreover + have "\ \ T1 <: S1" using ok extends ih1 by simp + ultimately show "\ \ \ [X<:S1].S2 <: \ [X<:T1].T2" using ok by (force intro: S_All) qed text {* more automated proof *} lemma weakening: - assumes a1: "\ \ S <: T" - shows "\ \ ok \ \ extends \ \ \ \ S <: T" - using a1 -proof (nominal_induct \ S T fresh: \ rule: subtype_of_rel_induct) + assumes a: "\ \ S <: T" + and b: "\ \ ok" + and c: "\ extends \" + shows "\ \ S <: T" + using a b c +proof (nominal_induct \ S T avoiding: \ rule: subtype_of_rel_induct) case (S_Top \ S) thus ?case by (force intro: extends_closed) next case (S_Var \ X S T) thus ?case by (force simp add: extends_def) @@ -672,43 +664,41 @@ next case (S_All \ X S1 S2 T1 T2) have fresh: "X\\" by fact - have ih1: "\\. \ \ ok \ \ extends \ \ \ \ T1 <: S1" by fact - have ih2: "\ \. \ \ ok \ \ extends ((X,T1)#\) \ \ \ S2 <: T2" by fact + have ih1: "\\. \ \ ok \ \ extends \ \ \ \ T1 <: S1" by fact + have ih2: "\\. \ \ ok \ \ extends ((X,T1)#\) \ \ \ S2 <: T2" by fact have lh_drv_prem: "\ \ T1 <: S1" by fact hence b5: "T1 closed_in \" by (simp add: subtype_implies_closed) - show "\ \ ok \ \ extends \ \ \ \ \ [X<:S1].S2 <: \ [X<:T1].T2" - proof (intro strip) - assume ok: "\ \ ok" - and extends: "\ extends \" - have "T1 closed_in \" using extends b5 by (simp only: extends_closed) - hence "\ ((X,T1)#\) ok" using fresh ok by force - moreover - have "((X,T1)#\) extends ((X,T1)#\)" using extends by (force simp add: extends_def) - ultimately have "((X,T1)#\) \ S2 <: T2" using ih2 by simp - moreover - have "\ \ T1 <: S1" using ok extends ih1 by simp - ultimately show "\ \ \ [X<:S1].S2 <: \ [X<:T1].T2" using ok by (force intro: S_All) - qed -qed + have ok: "\ \ ok" by fact + have extends: "\ extends \" by fact + have "T1 closed_in \" using extends b5 by (simp only: extends_closed) + hence "\ ((X,T1)#\) ok" using fresh ok by force + moreover + have "((X,T1)#\) extends ((X,T1)#\)" using extends by (force simp add: extends_def) + ultimately have "((X,T1)#\) \ S2 <: T2" using ih2 by simp + moreover + have "\ \ T1 <: S1" using ok extends ih1 by simp + ultimately show "\ \ \ [X<:S1].S2 <: \ [X<:T1].T2" using ok by (force intro: S_All) +qed (* helper lemma to calculate the measure of the induction *) lemma measure_eq [simp]: "(x, y) \ measure f = (f x < f y)" by (simp add: measure_def inv_image_def) - lemma transitivity_and_narrowing: - "(\\ S T. \ \ S <: Q \ \ \ Q <: T \ \ \ S <: T) \ - (\\ \ X P M N. (\@(X,Q)#\) \ M <: N \ \ \ P <: Q \ (\@(X,P)#\) \ M <: N)" + shows "(\\ S T. \ \ S <: Q \ \ \ Q <: T \ \ \ S <: T) \ + (\\ \ X P M N. (\@(X,Q)#\) \ M <: N \ \ \ P <: Q \ (\@(X,P)#\) \ M <: N)" proof (rule wf_induct [of "measure size_ty" _ Q, rule_format]) show "wf (measure size_ty)" by simp next case (goal2 Q) note IH1_outer = goal2[THEN conjunct1] and IH2_outer = goal2[THEN conjunct2, THEN spec, of _ "[]", simplified] - (* CHECK: Not clear whether the condition size_ty Q = size_ty Q' is needed, or whether - just doing it for Q'=Q is enough *) + + thm IH1_outer + thm IH2_outer + have transitivity: - "\\ S T. \ \ S <: Q \ \ \ Q <: T \ \ \ S <: T" + "\\ S T. \ \ S <: Q \ \ \ Q <: T \ \ \ S <: T" proof - (* We first handle the case where T = Top once and for all; this saves some @@ -735,146 +725,117 @@ (* Now proceed by induction on the left-hand derivation *) fix \ S T - assume a: "\ \ S <: Q" - from a show "\ \ Q <: T \ \ \ S <: T" - (* FIXME : nominal induct does not work here because Gamma S and Q are fixed variables *) - (* FIX: It would be better to use S',\',etc., instead of S1,\1, for consistency, in the cases - where these do not refer to sub-phrases of S, etc. *) - proof(nominal_induct \ S Q\Q fresh: \ S T rule: subtype_of_rel_induct) - (* interesting case *) - - case (goal1 \1 S1) --"lh drv.: \ \ S <: Q' \ \1 \ S1 <: Top" - --"automatic proof: thus ?case proof (auto intro!: S_Top dest: S_TopE)" - assume lh_drv_prem1: "\ \1 ok" - and lh_drv_prem2: "S1 closed_in \1" - and Q_eq: "Top=Q" - show "\1 \ Q <: T \ \1 \ S1 <: T" (* FIXME: why Ta? *) - proof (intro strip) - assume "\1 \ Q <: T" --"rh drv." - hence "T = Top" using Q_eq by (simp add: S_TopE) - thus "\1 \ S1 <: T" using top_case[of "\1" "S1" "False" "T"] lh_drv_prem1 lh_drv_prem2 - by simp - qed + assume a: "\ \ S <: Q" + assume b: "\ \ Q <: T" + from a b show "\ \ S <: T" + proof(nominal_induct \ S Q\Q avoiding: \ S T rule: subtype_of_rel_induct) + (* Q is immediately instanciated - no way to delay that? *) + case (S_Top \1 S1) --"lh drv.: \ \ S <: Q \ \1 \ S1 <: Top" + have lh_drv_prem1: "\ \1 ok" by fact + have lh_drv_prem2: "S1 closed_in \1" by fact + have Q_inst: "Top=Q" by fact + have rh_drv: "\1 \ Q <: T" --"rh drv." by fact + hence "T = Top" using Q_inst by (simp add: S_TopE) + thus "\1 \ S1 <: T" using top_case[of "\1" "S1" "False" "T"] lh_drv_prem1 lh_drv_prem2 + by simp next - case (goal2 \1 X1 S1 T1) --"lh drv.: \ \ S <: Q' \ \1 \ TVar(X1) <: S1" - --"automatic proof: thus ?case proof (auto intro!: S_Var)" + case (S_Var \1 X1 S1 T1) --"lh drv.: \ \ S <: Q \ \1 \ TVar(X1) <: S1" have lh_drv_prem1: "\ \1 ok" by fact have lh_drv_prem2: "(X1,S1)\set \1" by fact - have IH_inner: "\T. \1 \ T1 <: T \ \1 \ S1 <: T" by fact - show "\1 \ T1 <: Ta \ \1 \ TyVar X1 <: Ta" - proof (intro strip) - assume "\1 \ T1 <: Ta" --"right-hand drv." - with IH_inner have "\1 \ S1 <: Ta" by simp - thus "\1 \ TyVar X1 <: Ta" using lh_drv_prem1 lh_drv_prem2 by (simp add: S_Var) - qed + have IH_inner: "\T. \1 \ Q <: T \ T1=Q \ \1 \ S1 <: T" by fact + have Q_inst: "T1=Q" by fact + have rh_drv: "\1 \ Q <: T" by fact + with IH_inner have "\1 \ S1 <: T" using Q_inst by simp + thus "\1 \ TyVar X1 <: T" using lh_drv_prem1 lh_drv_prem2 by (simp add: subtype_of_rel.S_Var) next - case goal3 --"S_Refl case" show ?case by simp + case S_Refl --"S_Refl case" thus ?case by simp next - case (goal4 \1 S1 S2 T1 T2) --"lh drv.: \ \ S <: Q' == \1 \ S1 \ S2 <: T1 \ T2" + case (S_Arrow \1 S1 S2 T1 T2) --"lh drv.: \ \ S <: Q \ \1 \ S1 \ S2 <: T1 \ T2" have lh_drv_prem1: "\1 \ T1 <: S1" by fact have lh_drv_prem2: "\1 \ S2 <: T2" by fact - show "\1 \ T1 \ T2 <: T \ \1 \ S1 \ S2 <: T" - proof (intro strip) - (*assume measure: "size_ty Q = size_ty (T1 \ T2)" *) - assume rh_deriv: "\1 \ T1 \ T2 <: T'" - have "S1 closed_in \1" and "S2 closed_in \1" - using lh_drv_prem1 lh_drv_prem2 by (simp_all add: subtype_implies_closed) - hence "(S1 \ S2) closed_in \1" by (simp add: closed_in_def ty.supp) - moreover - have "\ \1 ok" using rh_deriv by (rule subtype_implies_ok) - moreover - have "T' = Top \ (\T3 T4. T'= T3 \ T4 \ \1 \ T3 <: T1 \ \1 \ T2 <: T4)" - using rh_deriv by (rule S_ArrowE_left) + have rh_deriv: "\1 \ Q <: T" by fact + have Q_inst: "T1 \ T2 = Q" by fact + have measure: "size_ty Q = size_ty (T1 \ T2)" using Q_inst by simp + have "S1 closed_in \1" and "S2 closed_in \1" + using lh_drv_prem1 lh_drv_prem2 by (simp_all add: subtype_implies_closed) + hence "(S1 \ S2) closed_in \1" by (simp add: closed_in_def ty.supp) + moreover + have "\ \1 ok" using rh_deriv by (rule subtype_implies_ok) + moreover + have "T = Top \ (\T3 T4. T= T3 \ T4 \ \1 \ T3 <: T1 \ \1 \ T2 <: T4)" + using rh_deriv Q_inst by (simp add:S_ArrowE_left) + moreover + { assume "\T3 T4. T= T3 \ T4 \ \1 \ T3 <: T1 \ \1 \ T2 <: T4" + then obtain T3 T4 + where T_inst: "T= T3 \ T4" + and rh_drv_prem1: "\1 \ T3 <: T1" + and rh_drv_prem2: "\1 \ T2 <: T4" by force + from IH1_outer[of "T1"] have "\1 \ T3 <: S1" + using measure rh_drv_prem1 lh_drv_prem1 by (force simp add: ty.inject) moreover - { assume "\T3 T4. T'= T3 \ T4 \ \1 \ T3 <: T1 \ \1 \ T2 <: T4" - then obtain T3 T4 - where T'_inst: "T'= T3 \ T4" - and rh_drv_prem1: "\1 \ T3 <: T1" - and rh_drv_prem2: "\1 \ T2 <: T4" by force - from IH1_outer[of "T1"] have "\1 \ T3 <: S1" - using measure rh_drv_prem1 lh_drv_prem1 by (force simp add: ty.inject) - moreover - from IH1_outer[of "T2"] have "\1 \ S2 <: T4" - using measure rh_drv_prem2 lh_drv_prem2 by (force simp add: ty.inject) - ultimately have "\1 \ S1 \ S2 <: T'" using T'_inst by force - } - ultimately show "\1 \ S1 \ S2 <: T'" using top_case[of "\1" "S1\S2" _ "T'"] by blast - qed + from IH1_outer[of "T2"] have "\1 \ S2 <: T4" + using measure rh_drv_prem2 lh_drv_prem2 by (force simp add: ty.inject) + ultimately have "\1 \ S1 \ S2 <: T" using T_inst by force + } + ultimately show "\1 \ S1 \ S2 <: T" using top_case[of "\1" "S1\S2" _ "T'"] by blast next - case (goal5 T' \1 X S1 S2 T1 T2) --"lh drv.: \ \ S <: Q' \ \1 \ \[X:S1].S2 <: \[X:T1].T2" + case (S_All \1 X S1 S2 T1 T2) --"lh drv.: \ \ S <: Q \ \1 \ \[X:S1].S2 <: \[X:T1].T2" have lh_drv_prem1: "\1 \ T1 <: S1" by fact have lh_drv_prem2: "((X,T1)#\1) \ S2 <: T2" by fact - have fresh_cond: "X\(\1,S1,T1)" by fact - show "size_ty Q = size_ty (\[X<:T1].T2) \ \1 \ \[X<:T1].T2 <: T' \ \1 \ \[X<:S1].S2 <: T'" - proof (intro strip) - assume measure: "size_ty Q = size_ty (\[X<:T1].T2)" - and rh_deriv: "\1 \ \[X<:T1].T2 <: T'" - have "S1 closed_in \1" and "S2 closed_in ((X,T1)#\1)" - using lh_drv_prem1 lh_drv_prem2 by (simp_all add: subtype_implies_closed) - hence "(\[X<:S1].S2) closed_in \1" by (force simp add: closed_in_def ty.supp abs_supp) - moreover - have "\ \1 ok" using rh_deriv by (rule subtype_implies_ok) - moreover + have rh_deriv: "\1 \ Q <: T" by fact + have fresh_cond: "X\\1" "X\S1" "X\T1" by fact + have Q_inst: "\[X<:T1].T2 = Q" by fact + have measure: "size_ty Q = size_ty (\[X<:T1].T2)" using Q_inst by simp + have "S1 closed_in \1" and "S2 closed_in ((X,T1)#\1)" + using lh_drv_prem1 lh_drv_prem2 by (simp_all add: subtype_implies_closed) + hence "(\[X<:S1].S2) closed_in \1" by (force simp add: closed_in_def ty.supp abs_supp) + moreover + have "\ \1 ok" using rh_deriv by (rule subtype_implies_ok) + moreover (* FIX: Maybe T3,T4 could be T1',T2' *) - have "T' = Top \ (\T3 T4. T'=\[X<:T3].T4 \ \1 \ T3 <: T1 \ ((X,T3)#\1) \ T2 <: T4)" - using rh_deriv fresh_cond by (auto dest: S_AllE_left simp add: fresh_prod) + have "T = Top \ (\T3 T4. T=\[X<:T3].T4 \ \1 \ T3 <: T1 \ ((X,T3)#\1) \ T2 <: T4)" + using rh_deriv fresh_cond Q_inst by (auto dest: S_AllE_left simp add: fresh_prod) + moreover + { assume "\T3 T4. T=\[X<:T3].T4 \ \1 \ T3 <: T1 \ ((X,T3)#\1) \ T2 <: T4" + then obtain T3 T4 + where T_inst: "T= \[X<:T3].T4" + and rh_drv_prem1: "\1 \ T3 <: T1" + and rh_drv_prem2:"((X,T3)#\1) \ T2 <: T4" by force + from IH1_outer[of "T1"] have "\1 \ T3 <: S1" + using lh_drv_prem1 rh_drv_prem1 measure by (force simp add: ty.inject) moreover - { assume "\T3 T4. T'=\[X<:T3].T4 \ \1 \ T3 <: T1 \ ((X,T3)#\1) \ T2 <: T4" - then obtain T3 T4 - where T'_inst: "T'= \[X<:T3].T4" - and rh_drv_prem1: "\1 \ T3 <: T1" - and rh_drv_prem2:"((X,T3)#\1) \ T2 <: T4" by force - from IH1_outer[of "T1"] have "\1 \ T3 <: S1" - using lh_drv_prem1 rh_drv_prem1 measure by (force simp add: ty.inject) - moreover - from IH2_outer[of "T1"] have "((X,T3)#\1) \ S2 <: T2" - using measure lh_drv_prem2 rh_drv_prem1 by force - with IH1_outer[of "T2"] have "((X,T3)#\1) \ S2 <: T4" - using measure rh_drv_prem2 by force - moreover - ultimately have "\1 \ \[X<:S1].S2 <: T'" - using fresh_cond T'_inst by (simp add: fresh_prod S_All) - } - ultimately show "\1 \ \[X<:S1].S2 <: T'" using top_case[of "\1" "\[X<:S1].S2" _ "T'"] by blast - qed + from IH2_outer[of "T1"] have "((X,T3)#\1) \ S2 <: T2" + using measure lh_drv_prem2 rh_drv_prem1 by force + with IH1_outer[of "T2"] have "((X,T3)#\1) \ S2 <: T4" + using measure rh_drv_prem2 by force + moreover + ultimately have "\1 \ \[X<:S1].S2 <: T" + using fresh_cond T_inst by (simp add: fresh_prod subtype_of_rel.S_All) + } + ultimately show "\1 \ \[X<:S1].S2 <: T" using Q_inst top_case[of "\1" "\[X<:S1].S2" _ "T'"] + by auto qed qed -(* test + (* HERE *) have narrowing: - "\\ \ X M N. (\@(X,Q)#\) \ M <: N \ (\P. \ \ P<:Q \ (\@(X,P)#\) \ M <: N)" - proof - - fix \ \ X M N - assume a: "(\@(X,Q)#\) \ M <: N" - thus "\P. \ \ P <: Q \ (\@(X,P)#\) \ M <: N" - thm subtype_of_rel_induct - thm subtype_of_rel.induct - using a proof (induct) - using a proof (induct rule: subtype_of_rel_induct[of "\@(X,Q)#\" "M" "N" _ "()"]) -*) - - have narrowing: - "\\ \ \' X M N. \' \ M <: N \ \' = \@(X,Q)#\ \ (\P. \ \ P<:Q \ (\@(X,P)#\) \ M <: N)" + "\\ \ X M N P. (\@(X,Q)#\) \ M <: N \ \ \ P<:Q \ (\@(X,Q)#\) \ M <: N" proof - - fix \ \ \' X M N - assume "\' \ M <: N" - thus "\' = \@(X,Q)#\ \ (\P. \ \ P <: Q \ (\@(X,P)#\) \ M <: N)" - (* FIXME : nominal induct does not work here because Gamma' M and N are fixed variables *) - (* FIX: Same comment about S1,\1 *) - proof (rule subtype_of_rel_induct[of "\'" "M" "N" "\\' M N (\,\,X). - \' = \@(X,Q)#\ \ (\P. \ \ P <: Q \ (\@(X,P)#\) \ M <: N)" "(\,\,X)", simplified], - simp_all only: split_paired_all split_conv) - case (goal1 \1 \1 X1 \2 S1) - have lh_drv_prem1: "\ \2 ok" by fact - have lh_drv_prem2: "S1 closed_in \2" by fact - show "\2 = \1@(X1,Q)#\1 \ (\P. \1 \ P <: Q \ (\1@(X1,P)#\1) \ S1 <: Top)" - proof (intro strip) - fix P - assume a1: "\2 = \1@(X1,Q)#\1" - assume a2: "\1 \ P <: Q" - from a2 have "P closed_in \1" by (simp add: subtype_implies_closed) - hence a3: "\ (\1@(X1,P)#\1) ok" using lh_drv_prem1 a1 by (rule_tac replace_type, simp_all) - show "(\1@(X1,P)#\1) \ S1 <: Top" + fix \ \ X M N P + assume a: "(\@(X,Q)#\) \ M <: N" + assume b: "\ \ P<:Q" + show "(\@(X,Q)#\) \ M <: N" + using a b + proof (nominal_induct \\"\@(X,Q)#\" M N avoiding: \ rule: subtype_of_rel_induct) + case (S_Top \1 S1 \2) + have lh_drv_prem1: "\ \1 ok" by fact + have lh_drv_prem2: "S1 closed_in \1" by fact + have \1_inst: "\1=\@(X,Q)#\2" by fact + have rh_drv: "\2 \ P <: Q" by fact + hence a1: "P closed_in \2" by (simp add: subtype_implies_closed) + hence a2: "\ (\@(X,P)#\2) ok" using lh_drv_prem1 a1 \1_inst by (simp add: replace_type) + show ?case + show "(\@(X,P)#\2) \ S1 <: Top" using a1 a3 lh_drv_prem2 by (force simp add: closed_in_def domain_append) qed next