25 |
23 |
26 text {* |
24 text {* |
27 The inductive relation 'unbind' unbinds the top-most |
25 The inductive relation 'unbind' unbinds the top-most |
28 binders of a lambda-term; this relation is obviously |
26 binders of a lambda-term; this relation is obviously |
29 not a function, since it does not respect alpha- |
27 not a function, since it does not respect alpha- |
30 equivalence. However as a relation unbind is ok and |
28 equivalence. However as a relation 'unbind' is ok and |
31 a similar relation has been used in our formalisation |
29 a similar relation has been used in our formalisation |
32 of the algorithm W. |
30 of the algorithm W. *} |
33 *} |
|
34 inductive |
31 inductive |
35 unbind :: "lam \<Rightarrow> name list \<Rightarrow> lam \<Rightarrow> bool" ("_ \<mapsto> _,_" [60,60,60] 60) |
32 unbind :: "lam \<Rightarrow> name list \<Rightarrow> lam \<Rightarrow> bool" ("_ \<mapsto> _,_" [60,60,60] 60) |
36 where |
33 where |
37 u_var: "(Var a) \<mapsto> [],(Var a)" |
34 u_var: "(Var a) \<mapsto> [],(Var a)" |
38 | u_app: "(App t1 t2) \<mapsto> [],(App t1 t2)" |
35 | u_app: "(App t1 t2) \<mapsto> [],(App t1 t2)" |
39 | u_lam: "t\<mapsto>xs,t' \<Longrightarrow> (Lam [x].t) \<mapsto> (x#xs),t'" |
36 | u_lam: "t\<mapsto>xs,t' \<Longrightarrow> (Lam [x].t) \<mapsto> (x#xs),t'" |
40 |
37 |
41 text {* |
38 text {* |
42 We can show that Lam [x]. Lam [x]. Var x unbinds to [x,x],Var x |
39 We can show that Lam [x].Lam [x].Var x unbinds to [x,x],Var x |
43 and also to [z,y],Var y (though the proof for the second is a |
40 and also to [z,y],Var y (though the proof for the second is a |
44 bit clumsy). |
41 bit clumsy). *} |
45 *} |
|
46 lemma unbind_lambda_lambda1: |
42 lemma unbind_lambda_lambda1: |
47 shows "Lam [x].Lam [x].(Var x)\<mapsto>[x,x],(Var x)" |
43 shows "Lam [x].Lam [x].(Var x)\<mapsto>[x,x],(Var x)" |
48 by (auto intro: unbind.intros) |
44 by (auto intro: unbind.intros) |
49 |
45 |
50 lemma unbind_lambda_lambda2: |
46 lemma unbind_lambda_lambda2: |
63 equivariance unbind |
59 equivariance unbind |
64 |
60 |
65 text {* |
61 text {* |
66 ... but it is not variable-convention compatible (see Urban, |
62 ... but it is not variable-convention compatible (see Urban, |
67 Berghofer, Norrish [2007] for more details). This condition |
63 Berghofer, Norrish [2007] for more details). This condition |
68 requires for rule u_lam, that the binder x is not a free variable |
64 requires for rule u_lam to have the binder x being not a free variable |
69 in the rule's conclusion. Because this condition is not satisfied, |
65 in the rule's conclusion. Because this condition is not satisfied, |
70 Isabelle will not derive a strong induction principle for unbind |
66 Isabelle will not derive a strong induction principle for 'unbind' |
71 - that means Isabelle does not allow you to use the variable |
67 - that means Isabelle does not allow us to use the variable |
72 convention in induction proofs involving unbind. We can, however, |
68 convention in induction proofs over 'unbind'. We can, however, |
73 force Isabelle to derive the strengthening induction principle. |
69 force Isabelle to derive the strengthening induction principle |
74 *} |
70 and see what happens. *} |
|
71 |
75 nominal_inductive unbind |
72 nominal_inductive unbind |
76 sorry |
73 sorry |
77 |
74 |
78 text {* |
75 text {* |
79 To obtain our faulty lemma, we introduce the function 'bind' |
76 To obtain a faulty lemma, we introduce the function 'bind' |
80 which takes a list of names and abstracts away these names in |
77 which takes a list of names and abstracts away these names in |
81 a given lambda-term. |
78 a given lambda-term. *} |
82 *} |
|
83 fun |
79 fun |
84 bind :: "name list \<Rightarrow> lam \<Rightarrow> lam" |
80 bind :: "name list \<Rightarrow> lam \<Rightarrow> lam" |
85 where |
81 where |
86 "bind [] t = t" |
82 "bind [] t = t" |
87 | "bind (x#xs) t = Lam [x].(bind xs t)" |
83 | "bind (x#xs) t = Lam [x].(bind xs t)" |
88 |
84 |
89 text {* |
85 text {* |
90 Although not necessary for our main argument below, we can |
86 Although not necessary for our main argument below, we can |
91 easily prove that bind undoes the unbinding. |
87 easily prove that bind undoes the unbinding. *} |
92 *} |
|
93 lemma bind_unbind: |
88 lemma bind_unbind: |
94 assumes a: "t \<mapsto> xs,t'" |
89 assumes a: "t \<mapsto> xs,t'" |
95 shows "t = bind xs t'" |
90 shows "t = bind xs t'" |
96 using a by (induct) (auto) |
91 using a by (induct) (auto) |
97 |
92 |
98 text {* |
93 text {* |
99 The next lemma shows by induction on xs that if x is a free |
94 The next lemma shows by induction on xs that if x is a free |
100 variable in t and x does not occur in xs, then x is a free |
95 variable in t and x does not occur in xs, then x is a free |
101 variable in bind xs t. In the nominal tradition we formulate |
96 variable in bind xs t. In the nominal tradition we formulate |
102 'is a free variable in' as 'is not fresh for'. |
97 'is a free variable in' as 'is not fresh for'. *} |
103 *} |
|
104 lemma free_variable: |
98 lemma free_variable: |
105 fixes x::"name" |
99 fixes x::"name" |
106 assumes a: "\<not>(x\<sharp>t)" and b: "x\<sharp>xs" |
100 assumes a: "\<not>(x\<sharp>t)" and b: "x\<sharp>xs" |
107 shows "\<not>(x\<sharp>bind xs t)" |
101 shows "\<not>(x\<sharp>bind xs t)" |
108 using a b |
102 using a b |
109 by (induct xs) |
103 by (induct xs) |
110 (auto simp add: fresh_list_cons abs_fresh fresh_atm) |
104 (auto simp add: fresh_list_cons abs_fresh fresh_atm) |
111 |
105 |
112 text {* |
106 text {* |
113 Now comes the faulty lemma. It is derived using the |
107 Now comes the faulty lemma. It is derived using the |
114 variable convention, that means using the strong induction |
108 variable convention (i.e. our strong induction principle). |
115 principle we 'proved' above by using sorry. This faulty |
109 This faulty lemma states that if t unbinds to x::xs and t', |
116 lemma states that if t unbinds to x::xs and t', and x is a |
110 and x is a free variable in t', then it is also a free |
117 free variable in t', then it is also a free variable in |
111 variable in bind xs t'. We show this lemma by assuming that |
118 bind xs t'. We show this lemma by assuming that the binder |
112 the binder x is fresh w.r.t. to the xs unbound previously. *} |
119 x is fresh w.r.t. to the xs unbound previously. |
113 |
120 *} |
|
121 lemma faulty1: |
114 lemma faulty1: |
122 assumes a: "t\<mapsto>(x#xs),t'" |
115 assumes a: "t\<mapsto>(x#xs),t'" |
123 shows "\<not>(x\<sharp>t') \<Longrightarrow> \<not>(x\<sharp>bind xs t')" |
116 shows "\<not>(x\<sharp>t') \<Longrightarrow> \<not>(x\<sharp>bind xs t')" |
124 using a |
117 using a |
125 by (nominal_induct t xs'\<equiv>"x#xs" t' avoiding: xs rule: unbind.strong_induct) |
118 by (nominal_induct t xs'\<equiv>"x#xs" t' avoiding: xs rule: unbind.strong_induct) |
126 (simp_all add: free_variable) |
119 (simp_all add: free_variable) |
127 |
120 |
128 text {* |
121 text {* |
129 Obviously the faulty lemma does not hold, for example, in |
122 Obviously the faulty lemma does not hold, for example, in |
130 case Lam [x].Lam [x].(Var x) \<mapsto> [x,x],(Var x). Therefore, |
123 case Lam [x].Lam [x].(Var x) \<mapsto> [x,x],(Var x). Therefore, |
131 we can prove False. |
124 we can prove False. *} |
132 *} |
125 |
133 lemma false1: |
126 lemma false1: |
134 shows "False" |
127 shows "False" |
135 proof - |
128 proof - |
136 have "Lam [x].Lam [x].(Var x)\<mapsto>[x,x],(Var x)" |
129 have "Lam [x].Lam [x].(Var x)\<mapsto>[x,x],(Var x)" |
137 and "\<not>(x\<sharp>Var x)" by (simp_all add: unbind_lambda_lambda1 fresh_atm) |
130 and "\<not>(x\<sharp>Var x)" by (simp_all add: unbind_lambda_lambda1 fresh_atm) |
143 qed |
136 qed |
144 |
137 |
145 text {* |
138 text {* |
146 The next example is slightly simpler, but looks more |
139 The next example is slightly simpler, but looks more |
147 contrived than 'unbind'. This example, caled 'strip' just |
140 contrived than 'unbind'. This example, caled 'strip' just |
148 strips off the top-most binders from lambdas. |
141 strips off the top-most binders from lambdas. *} |
149 *} |
|
150 |
142 |
151 inductive |
143 inductive |
152 strip :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<rightarrow> _" [60,60] 60) |
144 strip :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<rightarrow> _" [60,60] 60) |
153 where |
145 where |
154 s_var: "(Var a) \<rightarrow> (Var a)" |
146 s_var: "(Var a) \<rightarrow> (Var a)" |
155 | s_app: "(App t1 t2) \<rightarrow> (App t1 t2)" |
147 | s_app: "(App t1 t2) \<rightarrow> (App t1 t2)" |
156 | s_lam: "t \<rightarrow> t' \<Longrightarrow> (Lam [x].t) \<rightarrow> t'" |
148 | s_lam: "t \<rightarrow> t' \<Longrightarrow> (Lam [x].t) \<rightarrow> t'" |
157 |
149 |
158 text {* |
150 text {* |
159 The relation is equivariant but we have to use again |
151 The relation is equivariant but we have to use again |
160 sorry to derive a strong induction principle. |
152 sorry to derive a strong induction principle. *} |
161 *} |
153 |
162 equivariance strip |
154 equivariance strip |
163 |
155 |
164 nominal_inductive strip |
156 nominal_inductive strip |
165 sorry |
157 sorry |
166 |
158 |
167 text {* |
159 text {* |
168 The faulty lemma shows that a variable that is fresh |
160 The faulty lemma shows that a variable that is fresh |
169 for a term is also fresh for the term after striping. |
161 for a term is also fresh for the term after striping. *} |
170 *} |
162 |
171 lemma faulty2: |
163 lemma faulty2: |
172 fixes x::"name" |
164 fixes x::"name" |
173 assumes a: "t \<rightarrow> t'" |
165 assumes a: "t \<rightarrow> t'" |
174 shows "x\<sharp>t \<Longrightarrow> x\<sharp>t'" |
166 shows "x\<sharp>t \<Longrightarrow> x\<sharp>t'" |
175 using a |
167 using a |
176 by (nominal_induct t t'\<equiv>t' avoiding: t' rule: strip.strong_induct) |
168 by (nominal_induct t t'\<equiv>t' avoiding: t' rule: strip.strong_induct) |
177 (auto simp add: abs_fresh) |
169 (auto simp add: abs_fresh) |
178 |
170 |
179 text {* |
171 text {* |
180 Obviously Lam [x].Var x is a counter example to this lemma. |
172 Obviously Lam [x].Var x is a counter example to this lemma. *} |
181 *} |
173 |
182 lemma false2: |
174 lemma false2: |
183 shows "False" |
175 shows "False" |
184 proof - |
176 proof - |
185 have "Lam [x].(Var x) \<rightarrow> (Var x)" by (auto intro: strip.intros) |
177 have "Lam [x].(Var x) \<rightarrow> (Var x)" by (auto intro: strip.intros) |
186 moreover |
178 moreover |