# HG changeset patch # User urbanc # Date 1192986293 -7200 # Node ID 0835ac64834a93556d7189c7d545fedc2e33a21d # Parent 3cfa2a60837fca6635d016a7e54d4ea6c746988b polished the proofs and added a version of the weakening lemma that does not use the variable convention diff -r 3cfa2a60837f -r 0835ac64834a src/HOL/Nominal/Examples/Weakening.thy --- a/src/HOL/Nominal/Examples/Weakening.thy Sun Oct 21 17:48:11 2007 +0200 +++ b/src/HOL/Nominal/Examples/Weakening.thy Sun Oct 21 19:04:53 2007 +0200 @@ -9,57 +9,64 @@ atom_decl name +text {* Terms and types *} nominal_datatype lam = Var "name" | App "lam" "lam" | Lam "\name\lam" ("Lam [_]._" [100,100] 100) nominal_datatype ty = - TVar "nat" - | TArr "ty" "ty" (infix "\" 200) + TVar "string" + | TArr "ty" "ty" ("_ \ _" [100,100] 100) lemma ty_fresh: fixes x::"name" and T::"ty" shows "x\T" by (nominal_induct T rule: ty.induct) - (auto simp add: fresh_nat) + (auto simp add: fresh_string) -text {* valid contexts *} - +text {* + Valid contexts (at the moment we have no type for finite + sets yet; therefore typing-contexts are lists). *} inductive valid :: "(name\ty) list \ bool" where v1[intro]: "valid []" - | v2[intro]: "\valid \;a\\\\ valid ((a,\)#\)" + | v2[intro]: "\valid \;x\\\\ valid ((x,T)#\)" equivariance valid -text{* typing judgements *} +text{* Typing judgements *} inductive typing :: "(name\ty) list\lam\ty\bool" ("_ \ _ : _" [60,60,60] 60) where t_Var[intro]: "\valid \; (x,T)\set \\ \ \ \ Var x : T" | t_App[intro]: "\\ \ t1 : T1\T2; \ \ t2 : T1\ \ \ \ App t1 t2 : T2" - | t_Lam[intro]: "\x\\;((x,T1)#\) \ t : T2\ \ \ \ Lam [x].t : T1\T2" + | t_Lam[intro]: "\x\\;(x,T1)#\ \ t : T2\ \ \ \ Lam [x].t : T1\T2" +text {* + We automatically derive the strong induction principle + for the typing relation (this induction principle has the + variable convention already built in). *} equivariance typing - -(* automatically deriving the strong induction principle *) nominal_inductive typing by (simp_all add: abs_fresh ty_fresh) -text {* definition of a subcontext *} - +text {* Abbreviation for the notion of subcontexts. *} abbreviation "sub_context" :: "(name\ty) list \ (name\ty) list \ bool" ("_ \ _" [60,60] 60) where "\1 \ \2 \ \x T. (x,T)\set \1 \ (x,T)\set \2" text {* Now it comes: The Weakening Lemma *} +(*========================================*) +text {* + The first version is, after setting up the induction, + quite automatic except for use of atomize. *} lemma weakening_version1: - fixes \1 \2 :: "(name\ty) list" + fixes \1 \2::"(name\ty) list" assumes a: "\1 \ t : T" and b: "valid \2" and c: "\1 \ \2" @@ -68,8 +75,11 @@ by (nominal_induct \1 t T avoiding: \2 rule: typing.strong_induct) (auto | atomize)+ +text {* + The second version gives all details for the variable + and lambda case. *} lemma weakening_version2: - fixes \1::"(name\ty) list" + fixes \1 \2::"(name\ty) list" and t ::"lam" and \ ::"ty" assumes a: "\1 \ t : T" @@ -88,7 +98,7 @@ next case (t_Lam x \1 T1 t T2) (* lambda case *) have vc: "x\\2" by fact (* variable convention *) - have ih: "\valid ((x,T1)#\2); (x,T1)#\1 \ (x,T1)#\2\ \ (x,T1)#\2 \ t:T2" by fact + have ih: "\valid ((x,T1)#\2); (x,T1)#\1 \ (x,T1)#\2\ \ (x,T1)#\2 \ t:T2" by fact have "\1 \ \2" by fact then have "(x,T1)#\1 \ (x,T1)#\2" by simp moreover @@ -98,38 +108,19 @@ with vc show "\2 \ Lam [x].t : T1\T2" by auto qed (auto) (* app case *) -lemma weakening_version3: - fixes \1 \2 :: "(name\ty) list" - assumes a: "\1 \ t : T" - and b: "valid \2" - and c: "\1 \ \2" - shows "\2 \ t : T" -using a b c -proof (nominal_induct \1 t T avoiding: \2 rule: typing.strong_induct) - case (t_Lam x \1 T1 t T2) (* lambda case *) - have vc: "x\\2" by fact (* variable convention *) - have ih: "\\3. \valid \3; (x,T1)#\1 \ \3\ \ \3 \ t : T2" by fact - have "\1 \ \2" by fact - then have "(x,T1)#\1 \ (x,T1)#\2" by simp - moreover - have "valid \2" by fact - then have "valid ((x,T1)#\2)" using vc by (simp add: v2) - ultimately have "(x,T1)#\2 \ t : T2" using ih by simp - with vc show "\2 \ Lam [x].t : T1 \ T2" by auto -qed (auto) (* app and var case *) - -text{* The original induction principle for the typing relation - is not strong enough - even this simple lemma fails to be simple ;o) *} - -lemma weakening_too_weak: - fixes \1 \2 :: "(name\ty) list" +text{* + The original induction principle for the typing relation + is not strong enough - even this simple lemma fails to be + simple ;o) *} +lemma weakening_not_straigh_forward: + fixes \1 \2::"(name\ty) list" assumes a: "\1 \ t : T" and b: "valid \2" and c: "\1 \ \2" shows "\2 \ t : T" using a b c proof (induct arbitrary: \2) - case (t_Var \1 x T) (* variable case works *) + case (t_Var \1 x T) (* variable case still works *) have "\1 \ \2" by fact moreover have "valid \2" by fact @@ -138,15 +129,61 @@ ultimately show "\2 \ Var x : T" by auto next case (t_Lam x \1 T1 t T2) (* lambda case *) - (* all assumptions available in this case*) + (* These are all assumptions available in this case*) have a0: "x\\1" by fact have a1: "(x,T1)#\1 \ t : T2" by fact have a2: "\1 \ \2" by fact have a3: "valid \2" by fact - have ih: "\\3. \valid \3; (x,T1)#\1 \ \3\ \ \3 \ t : T2" by fact + have ih: "\\3. \valid \3; (x,T1)#\1 \ \3\ \ \3 \ t : T2" by fact have "(x,T1)#\1 \ (x,T1)#\2" using a2 by simp moreover have "valid ((x,T1)#\2)" using v2 (* fails *) oops + +text{* + The complete proof without using the variable convention. *} +lemma weakening_with_explicit_renaming: + fixes \1 \2::"(name\ty) list" + assumes a: "\1 \ t : T" + and b: "valid \2" + and c: "\1 \ \2" + shows "\2 \ t : T" +using a b c +proof (induct arbitrary: \2) + case (t_Lam x \1 T1 t T2) (* lambda case *) + have fc0: "x\\1" by fact + have ih: "\\3. \valid \3; (x,T1)#\1 \ \3\ \ \3 \ t : T2" by fact + obtain c::"name" where fc1: "c\(x,t,\1,\2)" (* we obtain a fresh name *) + by (rule exists_fresh) (auto simp add: fs_name1) + have "Lam [c].([(c,x)]\t) = Lam [x].t" using fc1 (* we alpha-rename the lambda-abstraction *) + by (auto simp add: lam.inject alpha fresh_prod fresh_atm) + moreover + have "\2 \ Lam [c].([(c,x)]\t) : T1 \ T2" (* we can then alpha-rename our original goal *) + proof - + (* we establish (x,T1)#\1 \ (x,T1)#([(c,x)]\\2) and valid ((x,T1)#([(c,x)]\\2)) *) + have "(x,T1)#\1 \ (x,T1)#([(c,x)]\\2)" + proof - + have "\1 \ \2" by fact + then have "[(c,x)]\((x,T1)#\1 \ (x,T1)#([(c,x)]\\2))" using fc0 fc1 + by (perm_simp add: eqvts calc_atm perm_fresh_fresh ty_fresh) + then show "(x,T1)#\1 \ (x,T1)#([(c,x)]\\2)" by (rule perm_boolE) + qed + moreover + have "valid ((x,T1)#([(c,x)]\\2))" + proof - + have "valid \2" by fact + then show "valid ((x,T1)#([(c,x)]\\2))" using fc1 + by (auto intro!: v2 simp add: fresh_left calc_atm eqvts) + qed + (* these two facts give us by induction hypothesis the following *) + ultimately have "(x,T1)#([(c,x)]\\2) \ t : T2" using ih by simp + (* we now apply renamings to get our goal *) + then have "[(c,x)]\((x,T1)#([(c,x)]\\2) \ t : T2)" by (rule perm_boolI) + then have "(c,T1)#\2 \ ([(c,x)]\t) : T2" using fc1 + by (perm_simp add: eqvts calc_atm perm_fresh_fresh ty_fresh) + then show "\2 \ Lam [c].([(c,x)]\t) : T1 \ T2" using fc1 by auto + qed + ultimately show "\2 \ Lam [x].t : T1 \ T2" by simp +qed (auto) end \ No newline at end of file