Skip to content

Commit 60fdf1f

Browse files
committed
Add syntax and substitution for case expressions
1 parent 77de9ba commit 60fdf1f

File tree

3 files changed

+148
-30
lines changed

3 files changed

+148
-30
lines changed

Defs.thy

Lines changed: 125 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,10 @@ nominal_function head_ctor :: "term \<Rightarrow> bool" where
3535
| "head_ctor (TApp e _) = head_ctor e"
3636
| "head_ctor (Ctor _) = True"
3737
| "head_ctor (Let _ _ _ _) = False"
38+
| "head_ctor (Case _ _) = False"
3839
proof goal_cases
3940
case (3 P x)
40-
then show ?case by (cases x rule: term.exhaust)
41+
then show ?case by (cases x rule: term_alts.exhaust(1))
4142
qed (auto simp: eqvt_def head_ctor_graph_aux_def)
4243
nominal_termination (eqvt) by lexicographic_order
4344

@@ -49,44 +50,92 @@ nominal_function is_value :: "term => bool" where
4950
| "is_value (TApp e \<tau>) = head_ctor e"
5051
| "is_value (Ctor _) = True"
5152
| "is_value (Let x \<tau> e1 e2) = False"
53+
| "is_value (Case _ _) = False"
5254
proof goal_cases
5355
case (3 P x)
54-
then show ?case by (cases x rule: term.exhaust)
56+
then show ?case by (cases x rule: term_alts.exhaust(1))
5557
next
56-
case (17 a k e a' k' e')
58+
case (19 a k e a' k' e')
5759
obtain c::tyvar where c: "atom c \<sharp> (a, e, a', e')" by (rule obtain_fresh)
5860
have 1: "is_value_sumC e' = (a' \<leftrightarrow> c) \<bullet> is_value_sumC e'" using permute_boolE permute_boolI by blast
5961
have 2: "is_value_sumC e = (a \<leftrightarrow> c) \<bullet> is_value_sumC e" using permute_boolE permute_boolI by blast
60-
from c have "(a \<leftrightarrow> c) \<bullet> e = (a' \<leftrightarrow> c) \<bullet> e'" using 17(5) by simp
61-
then show ?case using 1 2 17(1,2) eqvt_at_def by metis
62+
from c have "(a \<leftrightarrow> c) \<bullet> e = (a' \<leftrightarrow> c) \<bullet> e'" using 19(5) by simp
63+
then show ?case using 1 2 19(1,2) eqvt_at_def by metis
6264
qed (auto simp: eqvt_def is_value_graph_aux_def)
6365
nominal_termination (eqvt) by lexicographic_order
6466

65-
nominal_function subst_term :: "term => term \<Rightarrow> var => term" where
67+
nominal_function (default "case_sum (\<lambda>x. Inl undefined) (\<lambda>x. Inr undefined)")
68+
subst_term :: "term => term \<Rightarrow> var => term" and
69+
subst_alts :: "alts \<Rightarrow> term \<Rightarrow> var \<Rightarrow> alts" where
6670
"subst_term (Var y) e x = (if x = y then e else Var y)"
6771
| "subst_term (App e1 e2) e x = App (subst_term e1 e x) (subst_term e2 e x)"
6872
| "subst_term (TApp e1 \<tau>) e x = TApp (subst_term e1 e x) \<tau>"
6973
| "subst_term (Ctor D) _ _ = Ctor D"
74+
| "subst_term (Case t alts) e x = Case (subst_term t e x) (subst_alts alts e x)"
7075
| "atom y \<sharp> (e, x) \<Longrightarrow> subst_term (\<lambda> y:\<tau>. e2) e x = (\<lambda> y:\<tau>. subst_term e2 e x)"
7176
| "atom y \<sharp> (e, x) \<Longrightarrow> subst_term (\<Lambda> y:k. e2) e x = (\<Lambda> y:k. subst_term e2 e x)"
7277
| "atom y \<sharp> (e, x) \<Longrightarrow> subst_term (Let y \<tau> e1 e2) e x = Let y \<tau> (subst_term e1 e x) (subst_term e2 e x)"
78+
79+
| "subst_alts ANil _ _ = ANil"
80+
| "set (map atom tys @ map atom vals) \<sharp>* (e, x) \<Longrightarrow> subst_alts (Alt D tys vals t) e x = Alt D tys vals (subst_term t e x)"
7381
proof (goal_cases)
82+
(* this is adapted and simplified from here: https://www.joachim-breitner.de/thesis/isa/Substitution.thy *)
83+
have eqvt_at_subst_term: "\<And>e y z . eqvt_at subst_term_subst_alts_sumC (Inl (e, y, z)) \<Longrightarrow> eqvt_at (\<lambda>(a, b, c). subst_term a b c) (e, y, z)"
84+
apply (simp add: eqvt_at_def subst_term_def)
85+
apply rule
86+
apply (subst Projl_permute)
87+
apply (simp add: subst_term_subst_alts_sumC_def)
88+
apply (simp add: THE_default_def)
89+
apply (case_tac "Ex1 (subst_term_subst_alts_graph (Inl (e, y, z)))")
90+
apply(auto)[2]
91+
apply (erule_tac x="x" in allE)
92+
apply simp
93+
apply(cases rule: subst_term_subst_alts_graph.cases)
94+
apply(assumption)
95+
apply blast+
96+
apply simp
97+
done
98+
99+
{
74100
case (3 P x)
75-
then obtain t e y where P: "x = (t, e, y)" by (metis prod.exhaust)
76101
then show ?case
77-
apply (cases t rule: term.strong_exhaust[of _ _ "(e, y)"])
78-
apply (auto simp: 3)
79-
using 3(5-7) P fresh_star_def by blast+
102+
proof (cases x)
103+
case (Inl a)
104+
then obtain t e y where P: "a = (t, e, y)" by (metis prod.exhaust)
105+
then show ?thesis using Inl 3(1-5)
106+
proof (cases t rule: term_alts.strong_exhaust(1)[of _ _ "(e, y)"])
107+
case Lam
108+
then show ?thesis using 3(6) fresh_star_def Inl P by blast
109+
next
110+
case TyLam
111+
then show ?thesis using 3(7) fresh_star_def Inl P by blast
112+
next
113+
case Let
114+
then show ?thesis using 3(8) fresh_star_def Inl P by blast
115+
qed auto
116+
next
117+
case (Inr b)
118+
then obtain xs e y where P: "b = (xs, e, y)" by (metis prod.exhaust)
119+
then show ?thesis using Inr 3(9,10) by (cases xs rule: term_alts.strong_exhaust(2)[of _ _ "(e, y)"]) auto
120+
qed
121+
next
122+
case (44 y e x \<tau> e2 y' e' x' \<tau>' e2')
123+
have "(\<lambda> y : \<tau> . subst_term e2 e x) = (\<lambda> y' : \<tau>' . subst_term e2' e' x')" using Abs_sumC[OF 44(5,6) eqvt_at_subst_term[OF 44(1)] eqvt_at_subst_term[OF 44(2)]] 44(7) by fastforce
124+
then show ?case by (auto simp: Abs_fresh_iff meta_eq_to_obj_eq[OF subst_term_def, symmetric, unfolded fun_eq_iff])
80125
next
81-
case (26 y e x \<tau> e2 y' e' x' \<tau>' e2')
82-
then show ?case using Abs_sumC[OF 26(5,6,1,2)] by fastforce
126+
case (49 y e x k e2 y' e' x' k' e2')
127+
have "(\<Lambda> y : k . subst_term e2 e x) = (\<Lambda> y' : k' . subst_term e2' e' x')" using Abs_sumC[OF 49(5,6) eqvt_at_subst_term[OF 49(1)] eqvt_at_subst_term[OF 49(2)]] 49(7) by fastforce
128+
then show ?case by (auto simp: Abs_fresh_iff meta_eq_to_obj_eq[OF subst_term_def, symmetric, unfolded fun_eq_iff])
83129
next
84-
case (29 y e x k e2 y' e' x' k' e2')
85-
then show ?case using Abs_sumC[OF 29(5,6,1,2)] by fastforce
130+
case (53 y e x \<tau> e1 e2 y' e' x' \<tau>' e1' e2')
131+
have "Let y \<tau> (subst_term e1 e x) (subst_term e2 e x) = Let y' \<tau>' (subst_term e1' e' x') (subst_term e2' e' x')"
132+
using Abs_sumC[OF 53(9,10) eqvt_at_subst_term[OF 53(2)] eqvt_at_subst_term[OF 53(4)]] 53(11) by fastforce
133+
then show ?case by (auto simp: Abs_fresh_iff meta_eq_to_obj_eq[OF subst_term_def, symmetric, unfolded fun_eq_iff])
86134
next
87-
case (31 y e x \<tau> e1 e2 y' e' x' \<tau>' e1' e2')
88-
then show ?case using Abs_sumC[OF 31(9,10,2,4)] by fastforce
89-
qed (auto simp: eqvt_def subst_term_graph_aux_def)
135+
case (58 tys vals e x D t tys' vals' e' x' D' t')
136+
have "Alt D tys vals (subst_term t e x) = Alt D' tys' vals' (subst_term t' e' x')" using Abs_sumC_star[OF 58(5,6) eqvt_at_subst_term[OF 58(1)] eqvt_at_subst_term[OF 58(2)]] 58(7) by fastforce
137+
then show ?case by (auto simp: Abs_fresh_iff meta_eq_to_obj_eq[OF subst_term_def, symmetric, unfolded fun_eq_iff])
138+
} qed (auto simp: eqvt_def subst_term_subst_alts_graph_aux_def)
90139
nominal_termination (eqvt) by lexicographic_order
91140

92141
nominal_function subst_type :: "\<tau> \<Rightarrow> \<tau> \<Rightarrow> tyvar \<Rightarrow> \<tau>" where
@@ -108,31 +157,77 @@ next
108157
qed (auto simp: eqvt_def subst_type_graph_aux_def)
109158
nominal_termination (eqvt) by lexicographic_order
110159

111-
nominal_function subst_term_type :: "term \<Rightarrow> \<tau> \<Rightarrow> tyvar \<Rightarrow> term" where
160+
nominal_function (default "case_sum (\<lambda>x. Inl undefined) (\<lambda>x. Inr undefined)")
161+
subst_term_type :: "term \<Rightarrow> \<tau> \<Rightarrow> tyvar \<Rightarrow> term" and
162+
subst_alts_type :: "alts \<Rightarrow> \<tau> \<Rightarrow> tyvar \<Rightarrow> alts" where
112163
"subst_term_type (Var x) _ _ = Var x"
113164
| "subst_term_type (Ctor D) _ _ = Ctor D"
114165
| "subst_term_type (App e1 e2) \<tau> a = App (subst_term_type e1 \<tau> a) (subst_term_type e2 \<tau> a)"
115166
| "subst_term_type (TApp e \<tau>2) \<tau> a = TApp (subst_term_type e \<tau> a) (subst_type \<tau>2 \<tau> a)"
167+
| "subst_term_type (Case D alts) \<tau> a = Case D (subst_alts_type alts \<tau> a)"
116168
| "atom y \<sharp> (\<tau>, a) \<Longrightarrow> subst_term_type (\<lambda> y:\<tau>'. e2) \<tau> a = (\<lambda> y:(subst_type \<tau>' \<tau> a). subst_term_type e2 \<tau> a)"
117169
| "atom b \<sharp> (\<tau>, a) \<Longrightarrow> subst_term_type (\<Lambda> b:k. e2) \<tau> a = (\<Lambda> b:k. subst_term_type e2 \<tau> a)"
118170
| "atom y \<sharp> (\<tau>, a) \<Longrightarrow> subst_term_type (Let y \<tau>' e1 e2) \<tau> a = Let y (subst_type \<tau>' \<tau> a) (subst_term_type e1 \<tau> a) (subst_term_type e2 \<tau> a)"
171+
172+
| "subst_alts_type ANil _ _ = ANil"
173+
| "set (map atom tys @ map atom vals) \<sharp>* (\<tau>, a) \<Longrightarrow> subst_alts_type (Alt D tys vals e) \<tau> a = Alt D tys vals (subst_term_type e \<tau> a)"
119174
proof goal_cases
175+
(* this is adapted and simplified from here: https://www.joachim-breitner.de/thesis/isa/Substitution.thy *)
176+
have eqvt_at_subst_term_type: "\<And>e y z . eqvt_at subst_term_type_subst_alts_type_sumC (Inl (e, y, z)) \<Longrightarrow> eqvt_at (\<lambda>(a, b, c). subst_term_type a b c) (e, y, z)"
177+
apply (simp add: eqvt_at_def subst_term_type_def)
178+
apply rule
179+
apply (subst Projl_permute)
180+
apply (simp add: subst_term_type_subst_alts_type_sumC_def)
181+
apply (simp add: THE_default_def)
182+
apply (case_tac "Ex1 (subst_term_type_subst_alts_type_graph (Inl (e, y, z)))")
183+
apply(auto)[2]
184+
apply (erule_tac x="x" in allE)
185+
apply simp
186+
apply(cases rule: subst_term_type_subst_alts_type_graph.cases)
187+
apply(assumption)
188+
apply blast+
189+
apply simp
190+
done
191+
{
120192
case (3 P x)
121-
then obtain t \<tau> a where P: "x = (t, \<tau>, a)" by (metis prod.exhaust)
122193
then show ?case
123-
apply (cases t rule: term.strong_exhaust[of _ _ "(\<tau>, a)"])
124-
using 3 P apply auto[4]
125-
using 3(5,6,7) P fresh_star_def by blast+
194+
proof (cases x)
195+
case (Inl a)
196+
then obtain t \<tau> c where P: "a = (t, \<tau>, c)" by (metis prod.exhaust)
197+
then show ?thesis using 3 Inl
198+
proof (cases t rule: term_alts.strong_exhaust(1)[of _ _ "(\<tau>, c)"])
199+
case Lam
200+
then show ?thesis using 3(6) Inl P fresh_star_insert by blast
201+
next
202+
case TyLam
203+
then show ?thesis using 3(7) Inl P fresh_star_insert by blast
204+
next
205+
case Let
206+
then show ?thesis using 3(8) Inl P fresh_star_insert by blast
207+
qed auto
208+
next
209+
case (Inr b)
210+
then obtain xs \<tau> c where P: "b = (xs, \<tau>, c)" by (metis prod.exhaust)
211+
then show ?thesis using 3 Inr by (cases xs rule: term_alts.strong_exhaust(2)[of _ _ "(\<tau>, c)"]) auto
212+
qed
213+
next
214+
case (44 y \<tau> a \<tau>2 e2 y' \<tau>' a' \<tau>2' e2')
215+
have "(\<lambda> y : (subst_type \<tau>2 \<tau> a) . subst_term_type e2 \<tau> a) = (\<lambda> y' : (subst_type \<tau>2' \<tau>' a') . subst_term_type e2' \<tau>' a')" using Abs_sumC[OF 44(5,6) eqvt_at_subst_term_type[OF 44(1)] eqvt_at_subst_term_type[OF 44(2)]] 44(7) by fastforce
216+
then show ?case by (auto simp: Abs_fresh_iff meta_eq_to_obj_eq[OF subst_term_type_def, symmetric, unfolded fun_eq_iff])
126217
next
127-
case (26 y \<tau> a \<tau>1 e2 y' \<tau>' a' \<tau>1' e2')
128-
then show ?case using Abs_sumC[OF 26(5,6,1,2)] by fastforce
218+
case (49 b \<tau> a k e2 b' \<tau>' a' k' e2')
219+
have "(\<Lambda> b : k . subst_term_type e2 \<tau> a) = (\<Lambda> b' : k' . subst_term_type e2' \<tau>' a')" using Abs_sumC[OF 49(5,6) eqvt_at_subst_term_type[OF 49(1)] eqvt_at_subst_term_type[OF 49(2)]] 49(7) by fastforce
220+
then show ?case by (auto simp: Abs_fresh_iff meta_eq_to_obj_eq[OF subst_term_type_def, symmetric, unfolded fun_eq_iff])
129221
next
130-
case (29 b \<tau> a k e2 b' \<tau>' a' k' e2')
131-
then show ?case using Abs_sumC[OF 29(5,6,1,2)] by fastforce
222+
case (53 y \<tau> a \<tau>2 e1 e2 y' \<tau>' a' \<tau>2' e1' e2')
223+
have "Let y (subst_type \<tau>2 \<tau> a) (subst_term_type e1 \<tau> a) (subst_term_type e2 \<tau> a) = Let y' (subst_type \<tau>2' \<tau>' a') (subst_term_type e1' \<tau>' a') (subst_term_type e2' \<tau>' a')"
224+
using Abs_sumC[OF 53(9,10) eqvt_at_subst_term_type[OF 53(2)] eqvt_at_subst_term_type[OF 53(4)]] 53(11) by fastforce
225+
then show ?case by (auto simp: Abs_fresh_iff meta_eq_to_obj_eq[OF subst_term_type_def, symmetric, unfolded fun_eq_iff])
132226
next
133-
case (31 y \<tau> a \<tau>1 e1 e2 y' \<tau>' a' \<tau>1' e1' e2')
134-
then show ?case using Abs_sumC[OF 31(9,10,2,4)] by fastforce
135-
qed (auto simp: eqvt_def subst_term_type_graph_aux_def)
227+
case (58 tys vals \<tau> a D e tys' vals' \<tau>' a' D' e')
228+
have "Alt D tys vals (subst_term_type e \<tau> a) = Alt D' tys' vals' (subst_term_type e' \<tau>' a')" using Abs_sumC_star[OF 58(5,6) eqvt_at_subst_term_type[OF 58(1)] eqvt_at_subst_term_type[OF 58(2)]] 58(7) by fastforce
229+
then show ?case by (auto simp: Abs_fresh_iff meta_eq_to_obj_eq[OF subst_term_type_def, symmetric, unfolded fun_eq_iff])
230+
} qed (auto simp: eqvt_def subst_term_type_subst_alts_type_graph_aux_def)
136231
nominal_termination (eqvt) by lexicographic_order
137232

138233
nominal_function subst_context :: "\<Gamma> \<Rightarrow> \<tau> \<Rightarrow> tyvar \<Rightarrow> \<Gamma>" where
@@ -154,6 +249,6 @@ no_notation inverse_divide (infixl "'/" 70)
154249
consts subst :: "'a \<Rightarrow> 'b \<Rightarrow> 'c \<Rightarrow> 'a" ("_[_'/_]" [1000,0,0] 1000)
155250

156251
adhoc_overloading
157-
subst subst_term subst_type subst_term_type subst_context
252+
subst subst_term subst_alts subst_type subst_term_type subst_alts_type subst_context
158253

159254
end

Nominal2_Lemmas.thy

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,22 @@ proof -
6262
show ?thesis using 1 2 3 equal by argo
6363
qed
6464

65+
lemma Abs_sumC_star:
66+
fixes ys ys'::"atom list" and x::"'a::fs" and e::"'b::fs" and e2 e2'::"'c::fs" and f::"'c \<Rightarrow> 'b \<Rightarrow> 'a \<Rightarrow> 'd::fs"
67+
assumes fresh: "set ys \<sharp>* (e, x)" "set ys' \<sharp>* (e', x')"
68+
and eqvt_at: "eqvt_at (\<lambda>(a, b, c). f a b c) (e2, e, x)" "eqvt_at (\<lambda>(a, b, c). f a b c) (e2', e', x')"
69+
and equal: "[ys]lst. e2 = [ys']lst. e2'" "e = e'" "x = x'"
70+
shows "[ys]lst. f e2 e x = [ys']lst. f e2' e x"
71+
proof -
72+
have 1: "set ys \<sharp>* ([ys]lst. f e2 e x)" using Abs_fresh_star(3) by blast
73+
have 2: "\<And>p. supp p \<sharp>* (e, x) \<Longrightarrow> p \<bullet> ([ys]lst. f e2 e x) = [p \<bullet> ys]lst. f (p \<bullet> e2) e x"
74+
using eqvt_at(1) by (simp add: eqvt_at_def, simp add: fresh_star_Pair perm_supp_eq)
75+
have 3: "\<And>p. supp p \<sharp>* (e, x) \<Longrightarrow> p \<bullet> ([ys']lst. f e2' e x) = [p \<bullet> ys']lst. f (p \<bullet> e2') e x"
76+
using eqvt_at(2) equal(2,3) by (simp add: eqvt_at_def, simp add: fresh_star_Pair perm_supp_eq)
77+
78+
show ?thesis using Abs_lst_fcb2[where f="\<lambda>a b _. [a]lst. f b e x", OF equal(1) 1 fresh(1)] fresh(2) equal(2,3) 2 3 by argo
79+
qed
80+
6581
lemma Abs_fresh_var:
6682
fixes y::"'a::at" and e ::"'b::fs"
6783
obtains c::"'a" and e'::"'b" where "([[atom y]]lst. e = [[atom c]]lst. e') \<and> atom y \<sharp> [[atom c]]lst. e'"
@@ -79,4 +95,7 @@ lemma Abs_rename_body:
7995
shows "(a \<leftrightarrow> b) \<bullet> e1 = e2"
8096
by (metis Abs1_eq_iff'(3) Nominal2_Base.swap_self assms flip_commute flip_def fresh_star_zero supp_perm_eq_test)
8197

98+
lemma Projl_permute: "\<exists>y. f = Inl y \<Longrightarrow> p \<bullet> projl f = projl (p \<bullet> f)" by auto
99+
lemma Projr_permute: "\<exists>y. f = Inr y \<Longrightarrow> p \<bullet> projr f = projr (p \<bullet> f)" by auto
100+
82101
end

Syntax.thy

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ nominal_datatype "term" =
3030
| Lam x::"var" "\<tau>" e::"term" binds x in e ("\<lambda> _ : _ . _" 50)
3131
| TyLam a::"tyvar" "\<kappa>" e::"term" binds a in e ("\<Lambda> _ : _ . _" 50)
3232
| Let x::"var" "\<tau>" "term" e2::"term" binds x in e2
33+
| Case "term" alts
34+
and alts =
35+
ANil
36+
| Alt "ctor_name" tys::"tyvar list" terms::"var list" e::"term" binds tys terms in e
3337

3438
nominal_datatype "binder" =
3539
BVar "var" "\<tau>"

0 commit comments

Comments
 (0)