1044 we cannot have ``overlapping'' deep binders. Consider for example the |
1041 we cannot have ``overlapping'' deep binders. Consider for example the |
1045 term-constructors: |
1042 term-constructors: |
1046 |
1043 |
1047 \begin{center} |
1044 \begin{center} |
1048 \begin{tabular}{ll} |
1045 \begin{tabular}{ll} |
1049 @{text "Foo p::pat q::pat t::trm"} & |
1046 @{text "Foo\<^isub>1 p::pat q::pat t::trm"} & |
1050 \isacommand{bind} @{text "bn(p)"} \isacommand{in} @{text t},\; |
1047 \isacommand{bind} @{text "bn(p) bn(q)"} \isacommand{in} @{text t}\\ |
1051 \isacommand{bind} @{text "bn(q)"} \isacommand{in} @{text t}\\ |
1048 @{text "Foo\<^isub>2 x::name p::pat t::trm"} & |
1052 @{text "Foo' x::name p::pat t::trm"} & |
1049 \isacommand{bind} @{text "x bn(p)"} \isacommand{in} @{text t}\\ |
1053 \isacommand{bind} @{text x} \isacommand{in} @{text t},\; |
1050 \end{tabular} |
1054 \isacommand{bind} @{text "bn(p)"} \isacommand{in} @{text t} |
1051 \end{center} |
1055 \end{tabular} |
1052 |
1056 \end{center} |
1053 \noindent |
1057 |
1054 In the first case the intention is to bind all atoms from the pattern @{text p} in @{text t} |
1058 \noindent |
1055 and also all atoms from @{text q} in @{text t}. Unfortunately, we have no way |
1059 In the first case we might bind all atoms from the pattern @{text p} in @{text t} |
|
1060 and also all atoms from @{text q} in @{text t}. As a result we have no way |
|
1061 to determine whether the binder came from the binding function @{text |
1056 to determine whether the binder came from the binding function @{text |
1062 "bn(p)"} or @{text "bn(q)"}. Similarly in the second case. The reason why |
1057 "bn(p)"} or @{text "bn(q)"}. Similarly in the second case. The reason why |
1063 we must exclude such specifications is that they cannot be represent by |
1058 we must exclude such specifications is that they cannot be represent by |
1064 the general binders described in Section \ref{sec:binders}. However |
1059 the general binders described in Section \ref{sec:binders}. However |
1065 the following two term-constructors are allowed |
1060 the following two term-constructors are allowed |
1066 |
1061 |
1067 \begin{center} |
1062 \begin{center} |
1068 \begin{tabular}{ll} |
1063 \begin{tabular}{ll} |
1069 @{text "Bar p::pat t::trm s::trm"} & |
1064 @{text "Bar\<^isub>1 p::pat t::trm s::trm"} & |
1070 \isacommand{bind} @{text "bn(p)"} \isacommand{in} @{text t},\; |
1065 \isacommand{bind} @{text "bn(p)"} \isacommand{in} @{text "t s"}\\ |
1071 \isacommand{bind} @{text "bn(p)"} \isacommand{in} @{text s}\\ |
1066 @{text "Bar\<^isub>2 p::pat t::trm"} & |
1072 @{text "Bar' p::pat t::trm"} & |
1067 \isacommand{bind} @{text "bn(p)"} \isacommand{in} @{text "p t"}\\ |
1073 \isacommand{bind} @{text "bn(p)"} \isacommand{in} @{text p},\; |
|
1074 \isacommand{bind} @{text "bn(p)"} \isacommand{in} @{text t}\\ |
|
1075 \end{tabular} |
1068 \end{tabular} |
1076 \end{center} |
1069 \end{center} |
1077 |
1070 |
1078 \noindent |
1071 \noindent |
1079 since there is no overlap of binders. |
1072 since there is no overlap of binders. |
1080 |
1073 |
1081 Note that in the last example we wrote {\it\isacommand{bind}\;bn(p)\;\isacommand{in}\;p}. |
1074 Note that in the last example we wrote \isacommand{bind}~@{text "bn(p)"}~\isacommand{in}~@{text "p.."}. |
1082 Whenever such a binding clause is present, we will call the corresponding binder \emph{recursive}. |
1075 Whenever such a binding clause is present, we will call the corresponding binder \emph{recursive}. |
1083 To see the purpose of such recursive binders, compare ``plain'' @{text "Let"}s and @{text "Let_rec"}s |
1076 To see the purpose of such recursive binders, compare ``plain'' @{text "Let"}s and @{text "Let_rec"}s |
1084 in the following specification: |
1077 in the following specification: |
1085 % |
1078 % |
1086 \begin{equation}\label{letrecs} |
1079 \begin{equation}\label{letrecs} |
1107 "bn(as)"} in the term @{text t}, but with @{text "Let_rec"} we also want to bind the atoms |
1099 "bn(as)"} in the term @{text t}, but with @{text "Let_rec"} we also want to bind the atoms |
1108 inside the assignment. This difference has consequences for the free-variable |
1100 inside the assignment. This difference has consequences for the free-variable |
1109 function and alpha-equivalence relation, which we are going to describe in the |
1101 function and alpha-equivalence relation, which we are going to describe in the |
1110 rest of this section. |
1102 rest of this section. |
1111 |
1103 |
|
1104 In order to simplify matters below, we shall assume specifications |
|
1105 of term-calculi are \emph{completed}. By this we mean that |
|
1106 for every argument of a term-constructor that is \emph{not} |
|
1107 already part of a binding clause, we add implicitly a special \emph{empty} binding |
|
1108 clause, written \isacommand{bind}~@{term "{}"}~\isacommand{in}~@{text "\<dots>"}. In case |
|
1109 of the lambda-calculus, the comletion is as follows: |
|
1110 |
|
1111 \begin{center} |
|
1112 \begin{tabular}{@ {}l@ {\hspace{-1mm}}} |
|
1113 \isacommand{nominal\_datatype} @{text lam} =\\ |
|
1114 \hspace{5mm}\phantom{$\mid$}~@{text "Var x::name"} |
|
1115 \;\;\isacommand{bind}~@{term "{}"}~\isacommand{in}~@{text "x"}\\ |
|
1116 \hspace{5mm}$\mid$~@{text "App t\<^isub>1::lam t\<^isub>2::lam"} |
|
1117 \;\;\isacommand{bind}~@{term "{}"}~\isacommand{in}~@{text "t\<^isub>1"}, |
|
1118 \isacommand{bind}~@{term "{}"}~\isacommand{in}~@{text "t\<^isub>2"}\\ |
|
1119 \hspace{5mm}$\mid$~@{text "Lam x::name t::lam"} |
|
1120 \;\;\isacommand{bind}~@{text x} \isacommand{in} @{text t}\\ |
|
1121 \end{tabular} |
|
1122 \end{center} |
|
1123 |
|
1124 \noindent |
|
1125 The point of completion is that we can make definitions over the binding |
|
1126 clauses, which defined purely over arguments, turned out to be unwieldy. |
|
1127 |
1112 Having dealt with all syntax matters, the problem now is how we can turn |
1128 Having dealt with all syntax matters, the problem now is how we can turn |
1113 specifications into actual type definitions in Isabelle/HOL and then |
1129 specifications into actual type definitions in Isabelle/HOL and then |
1114 establish a reasoning infrastructure for them. As |
1130 establish a reasoning infrastructure for them. As |
1115 Pottier and Cheney pointed out \cite{Pottier06,Cheney5}, we cannot in general |
1131 Pottier and Cheney pointed out \cite{Pottier06,Cheney05}, by just |
1116 re-arrange arguments of |
1132 re-arranging the arguments of |
1117 term-constructors so that binders and their bodies are next to each other, and |
1133 term-constructors so that binders and their bodies are next to each other, and |
1118 then use the type constructors @{text "abs_set"}, @{text "abs_res"} and |
1134 then use directly the type constructors @{text "abs_set"}, @{text "abs_res"} and |
1119 @{text "abs_list"} from Section \ref{sec:binders}. Therefore we will first |
1135 @{text "abs_list"} from Section \ref{sec:binders}, will result in an inadequate |
|
1136 representatation. Therefore we will first |
1120 extract datatype definitions from the specification and then define |
1137 extract datatype definitions from the specification and then define |
1121 expicitly an alpha-equivalence relation over them. |
1138 expicitly an alpha-equivalence relation over them. |
1122 |
1139 |
1123 |
1140 |
1124 The datatype definition can be obtained by stripping off the |
1141 The datatype definition can be obtained by stripping off the |
1150 \begin{equation}\label{ceqvt} |
1167 \begin{equation}\label{ceqvt} |
1151 @{text "p \<bullet> (C x\<^isub>1 \<dots> x\<^isub>n) = C (p \<bullet> x\<^isub>1) \<dots> (p \<bullet> x\<^isub>n)"} |
1168 @{text "p \<bullet> (C x\<^isub>1 \<dots> x\<^isub>n) = C (p \<bullet> x\<^isub>1) \<dots> (p \<bullet> x\<^isub>n)"} |
1152 \end{equation} |
1169 \end{equation} |
1153 |
1170 |
1154 The first non-trivial step we have to perform is the generation free-variable |
1171 The first non-trivial step we have to perform is the generation free-variable |
1155 functions from the specifications. Given the raw types @{text "ty\<^isub>1 \<dots> ty\<^isub>n"} |
1172 functions from the specifications. For atomic types we define the auxilary |
1156 we need to define free-variable functions |
1173 free variable functions: |
1157 |
1174 |
1158 \begin{center} |
1175 \begin{center} |
1159 @{text "fv_ty\<^isub>1, \<dots>, fv_ty\<^isub>n"} |
1176 \begin{tabular}{r@ {\hspace{2mm}}c@ {\hspace{2mm}}l} |
1160 \end{center} |
1177 @{text "fv_atom a"} & @{text "="} & @{text "atom a"}\\ |
1161 |
1178 @{text "fv_atom_set as"} & @{text "="} & @{text "atoms as"}\\ |
1162 \noindent |
1179 @{text "fv_atom_list as"} & @{text "="} & @{text "atoms (set as)"}\\ |
1163 We define them together with auxiliary free-variable functions for |
1180 \end{tabular} |
1164 the binding functions. Given binding functions |
1181 \end{center} |
1165 @{text "bn\<^isub>1 \<dots> bn\<^isub>m"} we define |
|
1166 % |
|
1167 \begin{center} |
|
1168 @{text "fv_bn\<^isub>1, \<dots>, fv_bn\<^isub>m"} |
|
1169 \end{center} |
|
1170 |
|
1171 \noindent |
|
1172 The reason for this setup is that in a deep binder not all atoms have to be |
|
1173 bound, as we saw in the example with ``plain'' @{text Let}s. We need therefore a function |
|
1174 that calculates those unbound atoms. |
|
1175 |
|
1176 While the idea behind these |
|
1177 free-variable functions is clear (they just collect all atoms that are not bound), |
|
1178 because of our rather complicated binding mechanisms their definitions are |
|
1179 somewhat involved. |
|
1180 Given a term-constructor @{text "C"} of type @{text ty} with argument types |
|
1181 \mbox{@{text "ty\<^isub>1 \<dots> ty\<^isub>n"}}, the function |
|
1182 @{text "fv_ty (C x\<^isub>1 \<dots> x\<^isub>n)"} will be the union of the values, @{text v}, |
|
1183 calculated below for each argument. |
|
1184 First we deal with the case that @{text "x\<^isub>i"} is a binder. From the binding clauses, |
|
1185 we can determine whether the argument is a shallow or deep |
|
1186 binder, and in the latter case also whether it is a recursive or |
|
1187 non-recursive binder. |
|
1188 % |
|
1189 \begin{equation}\label{deepbinder} |
|
1190 \mbox{% |
|
1191 \begin{tabular}{c@ {\hspace{2mm}}p{7cm}} |
|
1192 $\bullet$ & @{term "v = {}"} provided @{text "x\<^isub>i"} is a shallow binder\\ |
|
1193 $\bullet$ & @{text "v = fv_bn x\<^isub>i"} provided @{text "x\<^isub>i"} is a deep |
|
1194 non-recursive binder with the auxiliary binding function @{text "bn"}\\ |
|
1195 $\bullet$ & @{text "v = fv_ty\<^isub>i x\<^isub>i - bn x\<^isub>i"} provided @{text "x\<^isub>i"} is |
|
1196 a deep recursive binder with the auxiliary binding function @{text "bn"} |
|
1197 \end{tabular}} |
|
1198 \end{equation} |
|
1199 |
|
1200 \noindent |
|
1201 The first clause states that shallow binders do not contribute to the |
|
1202 free variables; in the second clause, we have to collect all |
|
1203 variables that are left unbound by the binding function @{text "bn"}---this |
|
1204 is done with function @{text "fv_bn"}; in the third clause, since the |
|
1205 binder is recursive, we need to bind all variables specified by |
|
1206 @{text "bn"}---therefore we subtract @{text "bn x\<^isub>i"} from the free |
|
1207 variables of @{text "x\<^isub>i"}. |
|
1208 |
|
1209 In case the argument is \emph{not} a binder, we need to consider |
|
1210 whether the @{text "x\<^isub>i"} is the body of one or more binding clauses. |
|
1211 In this case we first calculate the set @{text "bnds"} as follows: |
|
1212 either the corresponding binders are all shallow or there is a single deep binder. |
|
1213 In the former case we take @{text bnds} to be the union of all shallow |
|
1214 binders; in the latter case, we just take the set of atoms specified by the |
|
1215 corresponding binding function. The value for @{text "x\<^isub>i"} is then given by: |
|
1216 % |
|
1217 \begin{equation}\label{deepbody} |
|
1218 \mbox{% |
|
1219 \begin{tabular}{c@ {\hspace{2mm}}p{7cm}} |
|
1220 $\bullet$ & @{text "v = {atom x\<^isub>i} - bnds"} provided @{term "x\<^isub>i"} is an atom\\ |
|
1221 $\bullet$ & @{text "v = (atoms x\<^isub>i) - bnds"} provided @{term "x\<^isub>i"} is a set of atoms\\ |
|
1222 $\bullet$ & @{text "v = (atoms (set x\<^isub>i)) - bnds"} provided @{term "x\<^isub>i"} is a list of atoms\\ |
|
1223 $\bullet$ & @{text "v = (fv_ty\<^isub>i x\<^isub>i) - bnds"} provided @{term "ty\<^isub>i"} is one of the raw datatypes |
|
1224 corresponding to the types specified by the user\\ |
|
1225 % $\bullet$ & @{text "(fv\<^isup>\<alpha> x\<^isub>i) - bnds"} provided @{term "x\<^isub>i"} is a defined nominal datatype |
|
1226 % with a free-variable function @{text "fv\<^isup>\<alpha>"}\\ |
|
1227 $\bullet$ & @{term "v = {}"} otherwise |
|
1228 \end{tabular}} |
|
1229 \end{equation} |
|
1230 |
1182 |
1231 \noindent |
1183 \noindent |
1232 Like the coercion function @{text atom} used earlier, @{text "atoms"} coerces |
1184 Like the coercion function @{text atom} used earlier, @{text "atoms"} coerces |
1233 the set of atoms to a set of the generic atom type. |
1185 the set of atoms to a set of the generic atom type. |
1234 It is defined as @{text "atoms as \<equiv> {atom a | a \<in> as}"}. |
1186 It is defined as @{text "atoms as \<equiv> {atom a | a \<in> as}"}. |
1235 |
1187 |
1236 The last case we need to consider is when @{text "x\<^isub>i"} is neither |
1188 Given the raw types @{text "ty\<^isub>1 \<dots> ty\<^isub>n"} |
1237 a binder nor a body of an abstraction. In this case it is defined |
1189 we define now free-variable functions |
1238 as in \eqref{deepbody}, except that we do not need to subtract the |
1190 |
1239 set @{text bnds}. |
1191 \begin{center} |
1240 |
1192 @{text "fv_ty\<^isub>1, \<dots>, fv_ty\<^isub>n"} |
1241 The definitions of the free-variable functions for binding |
1193 \end{center} |
1242 functions are similar. For each binding function |
1194 |
1243 @{text "bn\<^isub>j"} we need to define a free-variable function |
1195 \noindent |
1244 @{text "fv_bn\<^isub>j"}. Given a term-constructor @{term "C"}, the |
1196 We define them together with auxiliary free-variable functions for |
1245 function @{text "fv_bn\<^isub>j(C x\<^isub>1 \<dots> x\<^isub>n)"} is the union of the |
1197 the binding functions. Given binding functions |
1246 values calculated for the arguments. For each argument @{term "x\<^isub>i"} |
1198 @{text "bn\<^isub>1 \<dots> bn\<^isub>m"} we define |
1247 we know whether it appears in the @{term "rhs"} of the binding |
1199 % |
1248 function equation @{text "bn\<^isub>j (C x\<^isub>1 \<dots> x\<^isub>n) = rhs"}. If it does not |
1200 \begin{center} |
1249 appear in @{text "rhs"} we generate the premise according to the |
1201 @{text "fv_bn\<^isub>1, \<dots>, fv_bn\<^isub>m"} |
1250 rules for @{text "fv_ty"} described above in (\ref{deepbinder}--\ref{deepbody}). Otherwise: |
1202 \end{center} |
1251 |
1203 |
1252 \begin{center} |
1204 \noindent |
|
1205 The reason for this setup is that in a deep binder not all atoms have to be |
|
1206 bound, as we saw in the example with ``plain'' @{text Let}s. We need therefore a function |
|
1207 that calculates those unbound atoms. |
|
1208 |
|
1209 While the idea behind these free-variable functions is clear (they just |
|
1210 collect all atoms that are not bound), because of our rather complicated |
|
1211 binding mechanisms their definitions are somewhat involved. Given a |
|
1212 term-constructor @{text "C"} of type @{text ty} and some associated binding |
|
1213 clauses, the function @{text "fv_ty (C x\<^isub>1 \<dots> x\<^isub>n)"} will be |
|
1214 the union of the values, @{text v}, calculated below for each binding |
|
1215 clause. |
|
1216 |
|
1217 \begin{equation}\label{deepbinder} |
|
1218 \mbox{% |
1253 \begin{tabular}{c@ {\hspace{2mm}}p{7cm}} |
1219 \begin{tabular}{c@ {\hspace{2mm}}p{7cm}} |
1254 $\bullet$ & @{text "v = fv_bn x\<^isub>i"} provided @{text "rhs"} contains the |
1220 \multicolumn{2}{@ {}l}{Empty binding clauses of the form |
1255 recursive call @{text "bn x\<^isub>i"}\medskip\\ |
1221 \isacommand{bind\_set}~@{term "{}"}~\isacommand{in}~@{text "y"}:}\\ |
1256 $\bullet$ & @{term "v = {}"} provided @{text "rhs"} contains |
1222 $\bullet$ & @{term "v = fv_ty y"} provided @{text "y"} is of type @{text "ty"}\smallskip\\ |
1257 @{term "x\<^isub>i"} and @{term "x\<^isub>i"} is of atom type. |
1223 \multicolumn{2}{@ {}l}{Shallow binders of the form |
1258 \end{tabular} |
1224 \isacommand{bind\_set}~@{text "x\<^isub>1\<dots>x\<^isub>n"}~\isacommand{in}~@{text "y\<^isub>1\<dots>y\<^isub>m"}:}\\ |
1259 \end{center} |
1225 $\bullet$ & @{text "v = (fv_ty\<^isub>1 y\<^isub>1 \<union> fv_ty\<^isub>m y\<^isub>m) - (x\<^isub>1 \<union> \<dots> \<union> x\<^isub>n)"} |
1260 |
1226 provided the @{text "y\<^isub>i"} are of type @{text "ty\<^isub>i"}\smallskip\\ |
1261 \noindent |
1227 \multicolumn{2}{@ {}l}{Deep binders of the form |
|
1228 \isacommand{bind\_set}~@{text "bn x"}~\isacommand{in}~@{text "y\<^isub>1\<dots>y\<^isub>m"}:}\\ |
|
1229 $\bullet$ & @{text "v = (fv_ty\<^isub>1 y\<^isub>1 \<union> fv_ty\<^isub>m y\<^isub>m) - (bn x) \<union> (fv_bn x)"}\\ |
|
1230 $\bullet$ & @{text "v = (fv_ty\<^isub>1 y\<^isub>1 \<union> fv_ty\<^isub>m y\<^isub>m) - (bn x)"}\\ |
|
1231 & provided the @{text "y\<^isub>i"} are of type @{text "ty\<^isub>i"}; the first |
|
1232 clause applies for @{text x} being a non-recursive deep binder, the |
|
1233 second for a recursive deep binder |
|
1234 \end{tabular}} |
|
1235 \end{equation} |
|
1236 |
|
1237 \noindent |
|
1238 Similarly for the other binding modes. Note that in a non-recursive deep |
|
1239 binder, we have to add all atoms that are left unbound by the binding |
|
1240 function @{text "bn"}. For this we use the function @{text "fv_bn"}. Assume |
|
1241 for the constructor @{text "C"} the binding function equation is of the form @{text |
|
1242 "bn\<^isub>j (C x\<^isub>1 \<dots> x\<^isub>n) = rhs"}. We again define a value |
|
1243 @{text v} which is exactly as in \eqref{deepbinder} for shallow and deep |
|
1244 binders. We only modify the clause for empty binding clauses as follows: |
|
1245 |
|
1246 |
|
1247 \begin{equation}\label{bnemptybinder} |
|
1248 \mbox{% |
|
1249 \begin{tabular}{c@ {\hspace{2mm}}p{7cm}} |
|
1250 \multicolumn{2}{@ {}l}{Empty binding clauses of the form |
|
1251 \isacommand{bind\_set}~@{term "{}"}~\isacommand{in}~@{text "y"}:}\\ |
|
1252 $\bullet$ & @{term "v = fv_ty\<^isub>i y"} provided @{text "y"} does not occur in @{text "rhs"} |
|
1253 and the free-variable function for the type of @{text "y"} is @{text "fv_ty\<^isub>i"}\\ |
|
1254 $\bullet$ & @{term "v = fv_bn\<^isub>i y"} provided @{text "y"} occurs in @{text "rhs"} |
|
1255 with a recursive call @{text "bn\<^isub>i y"}\\ |
|
1256 $\bullet$ & @{term "v = {}"} provided @{text "y"} occurs in @{text "rhs"}, |
|
1257 but without a recursive call\\ |
|
1258 \end{tabular}} |
|
1259 \end{equation} |
|
1260 |
|
1261 \noindent |
|
1262 The reason why we only have to treat the empty binding clauses specially in |
|
1263 the definition of @{text "fv_bn"} is that binding functions can only use arguments |
|
1264 that do not occur in binding clauses. Otherwise the @{text "bn"} function cannot |
|
1265 be lifted to alpha-equated terms. |
|
1266 |
|
1267 |
1262 To see how these definitions work in practice, let us reconsider the term-constructors |
1268 To see how these definitions work in practice, let us reconsider the term-constructors |
1263 @{text "Let"} and @{text "Let_rec"} from the example shown in \eqref{letrecs}. |
1269 @{text "Let"} and @{text "Let_rec"} from the example shown in \eqref{letrecs}. |
1264 For this specification we need to define three free-variable functions, namely |
1270 For this specification we need to define three free-variable functions, namely |
1265 @{text "fv\<^bsub>trm\<^esub>"}, @{text "fv\<^bsub>assn\<^esub>"} and @{text "fv\<^bsub>bn\<^esub>"}. They are as follows: |
1271 @{text "fv\<^bsub>trm\<^esub>"}, @{text "fv\<^bsub>assn\<^esub>"} and @{text "fv\<^bsub>bn\<^esub>"}. They are as follows: |
1266 % |
1272 % |
1267 \begin{center} |
1273 \begin{center} |
1268 \begin{tabular}{@ {}l@ {\hspace{1mm}}c@ {\hspace{1mm}}l@ {}} |
1274 \begin{tabular}{@ {}l@ {\hspace{1mm}}c@ {\hspace{1mm}}l@ {}} |
1269 @{text "fv\<^bsub>trm\<^esub> (Let as t)"} & @{text "="} & @{text "fv\<^bsub>bn\<^esub> as \<union> (fv\<^bsub>trm\<^esub> t - set (bn as))"}\\ |
1275 @{text "fv\<^bsub>trm\<^esub> (Let as t)"} & @{text "="} & @{text "(fv\<^bsub>trm\<^esub> t - set (bn as)) \<union> fv\<^bsub>bn\<^esub> as"}\\ |
1270 @{text "fv\<^bsub>trm\<^esub> (Let_rec as t)"} & @{text "="} &\\ |
1276 @{text "fv\<^bsub>trm\<^esub> (Let_rec as t)"} & @{text "="} & @{text "(fv\<^bsub>assn\<^esub> as \<union> fv\<^bsub>trm\<^esub> t) - set (bn as)"}\\[1mm] |
1271 \multicolumn{3}{r}{@{text "(fv\<^bsub>assn\<^esub> as - set (bn as)) \<union> (fv\<^bsub>trm\<^esub> t - set (bn as))"}}\\[1mm] |
1277 |
1272 |
1278 @{text "fv\<^bsub>assn\<^esub> (ANil)"} & @{text "="} & @{term "{}"}\\ |
1273 @{text "fv\<^bsub>assn\<^esub> (ANil)"} & @{text "="} & @{text "[]"}\\ |
|
1274 @{text "fv\<^bsub>assn\<^esub> (ACons a t as)"} & @{text "="} & @{text "{atom a} \<union> (fv\<^bsub>trm\<^esub> t) \<union> (fv\<^bsub>assn\<^esub> as)"}\\[1mm] |
1279 @{text "fv\<^bsub>assn\<^esub> (ACons a t as)"} & @{text "="} & @{text "{atom a} \<union> (fv\<^bsub>trm\<^esub> t) \<union> (fv\<^bsub>assn\<^esub> as)"}\\[1mm] |
1275 |
1280 |
1276 @{text "fv\<^bsub>bn\<^esub> (ANil)"} & @{text "="} & @{text "[]"}\\ |
1281 @{text "fv\<^bsub>bn\<^esub> (ANil)"} & @{text "="} & @{term "{}"}\\ |
1277 @{text "fv\<^bsub>bn\<^esub> (ACons a t as)"} & @{text "="} & @{text "(fv\<^bsub>trm\<^esub> t) \<union> (fv\<^bsub>bn\<^esub> as)"} |
1282 @{text "fv\<^bsub>bn\<^esub> (ACons a t as)"} & @{text "="} & @{text "(fv\<^bsub>trm\<^esub> t) \<union> (fv\<^bsub>bn\<^esub> as)"} |
1278 \end{tabular} |
1283 \end{tabular} |
1279 \end{center} |
1284 \end{center} |
1280 |
1285 |
1281 \noindent |
1286 \noindent |
1282 Since there are no binding clauses for the term-constructors @{text ANil} |
1287 Since there are only (implicit) empty binding clauses for the term-constructors @{text ANil} |
1283 and @{text "ACons"}, the corresponding free-variable function @{text |
1288 and @{text "ACons"}, the corresponding free-variable function @{text |
1284 "fv\<^bsub>assn\<^esub>"} returns all atoms occuring in an assignment. The |
1289 "fv\<^bsub>assn\<^esub>"} returns all atoms occuring in an assignment. The |
1285 binding only takes place in @{text Let} and @{text "Let_rec"}. In the @{text |
1290 binding only takes place in @{text Let} and @{text "Let_rec"}. In the @{text |
1286 "Let"}-clause we want to bind all atoms given by @{text "set (bn as)"} in |
1291 "Let"}-clause we want to bind all atoms given by @{text "set (bn as)"} in |
1287 @{text t}. Therefore we have to subtract @{text "set (bn as)"} from @{text |
1292 @{text t}. Therefore we have to subtract @{text "set (bn as)"} from @{text |
1288 "fv\<^bsub>trm\<^esub> t"}. However, we also need to add all atoms that are |
1293 "fv\<^bsub>trm\<^esub> t"}. However, we also need to add all atoms that are |
1289 free in @{text "as"}. This is what the purpose of the function @{text |
1294 free in @{text "as"}. This is what the purpose of the function @{text |
1290 "fv\<^bsub>bn\<^esub>"} is. In contrast, in @{text "Let_rec"} we have a |
1295 "fv\<^bsub>bn\<^esub>"} is. In contrast, in @{text "Let_rec"} we have a |
1291 recursive binder where we want to also bind all occurrences of the atoms |
1296 recursive binder where we want to also bind all occurrences of the atoms |
1292 in @{text "set (bn as)"} inside @{text "as"}. Therefore we have to subtract @{text |
1297 in @{text "set (bn as)"} inside @{text "as"}. Therefore we have to subtract @{text |
1293 "set (bn as)"} from @{text "fv\<^bsub>assn\<^esub> as"}, as well as from |
1298 "set (bn as)"} from @{text "fv\<^bsub>trm\<^esub> t"}, as well as from |
1294 @{text "fv\<^bsub>trm\<^esub> t"}. An interesting point in this example is |
1299 @{text "fv\<^bsub>assn\<^esub> as"}. An interesting point in this example is |
1295 that an assignment ``alone'' does not have any bound variables. Only in the |
1300 that an assignment ``alone'' does not have any bound variables. Only in the |
1296 context of a @{text Let} or @{text "Let_rec"} will some atoms become bound. |
1301 context of a @{text Let} or @{text "Let_rec"} will some atoms become bound. |
1297 This is a phenomenon |
1302 This is a phenomenon |
1298 that has also been pointed out in \cite{ott-jfp}. We can also see that |
1303 that has also been pointed out in \cite{ott-jfp}. For us it is crucial, because |
|
1304 we would not be able to lift a @{text "bn"}-function that is defined over |
|
1305 arguments that are either binders or bodies. In that case @{text "bn"} would |
|
1306 not respect alpha-equivalence. We can also see that |
1299 % |
1307 % |
1300 \begin{equation}\label{bnprop} |
1308 \begin{equation}\label{bnprop} |
1301 @{text "fv_ty x = bn x \<union> fv_bn x"}. |
1309 @{text "fv_ty x = bn x \<union> fv_bn x"}. |
1302 \end{equation} |
1310 \end{equation} |
1303 |
1311 |
1346 fv_trm ("fv\<^bsub>trm\<^esub>") and |
1351 fv_trm ("fv\<^bsub>trm\<^esub>") and |
1347 alpha_trm2 ("\<approx>\<^bsub>assn\<^esub> \<otimes> \<approx>\<^bsub>trm\<^esub>") and |
1352 alpha_trm2 ("\<approx>\<^bsub>assn\<^esub> \<otimes> \<approx>\<^bsub>trm\<^esub>") and |
1348 fv_trm2 ("fv\<^bsub>assn\<^esub> \<oplus> fv\<^bsub>trm\<^esub>") |
1353 fv_trm2 ("fv\<^bsub>assn\<^esub> \<oplus> fv\<^bsub>trm\<^esub>") |
1349 (*>*) |
1354 (*>*) |
1350 text {* |
1355 text {* |
1351 \begin{itemize} |
1356 \begin{equation}\label{alpha} |
1352 \item The @{text "(x\<^isub>i, y\<^isub>i)"} is a body of shallow binder with type @{text "ty"}. We assume the |
1357 \mbox{% |
1353 \mbox{@{text "(u\<^isub>1, v\<^isub>1),\<dots>,(u\<^isub>m, v\<^isub>m)"}} are the corresponding binders. For the binding mode |
1358 \begin{tabular}{c@ {\hspace{2mm}}p{7cm}} |
1354 \isacommand{bind\_set} we generate the premise |
1359 \multicolumn{2}{@ {}l}{Empty binding clauses of the form |
1355 \begin{center} |
1360 \isacommand{bind\_set}~@{term "{}"}~\isacommand{in}~@{text "x\<^isub>i"}:}\\ |
1356 @{term "\<exists>p. (u\<^isub>1 \<union> \<xi> \<union> u\<^isub>m, x\<^isub>i) \<approx>gen alpha_ty fv_ty p (v\<^isub>1 \<union> \<xi> \<union> v\<^isub>m, y\<^isub>i)"} |
1361 $\bullet$ & @{text "x\<^isub>i \<approx>ty y\<^isub>i"} provided @{text "x\<^isub>i"} and @{text "y\<^isub>i"} |
1357 \end{center} |
1362 are recursive arguments of @{text "C"}\\ |
1358 |
1363 $\bullet$ & @{term "x\<^isub>i = y\<^isub>i"} provided @{text "x\<^isub>i"} and @{text "y\<^isub>i"} are |
1359 For the binding mode \isacommand{bind}, we use $\approx_{\textit{list}}$, and for |
1364 non-recursive arguments\smallskip\\ |
1360 binding mode \isacommand{bind\_res} we use $\approx_{\textit{res}}$ instead. |
1365 \multicolumn{2}{@ {}l}{Shallow binders of the form |
1361 |
1366 \isacommand{bind\_set}~@{text "x\<^isub>1\<dots>x\<^isub>n"}~\isacommand{in}~@{text "x'\<^isub>1\<dots>x'\<^isub>m"}:}\\ |
1362 \item The @{text "(x\<^isub>i, y\<^isub>i)"} is a deep non-recursive binder with type @{text "ty"} |
1367 $\bullet$ & Assume the bodies @{text "x'\<^isub>1\<dots>x'\<^isub>m"} are of type @{text "ty\<^isub>1\<dots>ty\<^isub>m"}, |
1363 and @{text bn} is corresponding the binding function. We assume |
1368 @{text "R"} is @{text "\<approx>ty\<^isub>1 \<otimes> ... \<otimes> \<approx>ty\<^isub>m"} and @{text fv} is |
1364 @{text "(u\<^isub>1, v\<^isub>1),\<dots>,(u\<^isub>m, v\<^isub>m)"} are the corresponding bodies with types @{text "ty\<^isub>1,\<dots>, ty\<^isub>m"}. |
1369 @{text "fv_ty\<^isub>1 \<oplus> ... \<oplus> fv_ty\<^isub>m"}, then |
1365 For the binding mode \isacommand{bind\_set} we generate two premises |
1370 \begin{center} |
1366 % |
1371 @{term "\<exists>p. (x\<^isub>1 \<union> \<xi> \<union> x\<^isub>n, (x'\<^isub>1,\<xi>,x'\<^isub>m)) \<approx>gen R fv p (y\<^isub>1 \<union> \<xi> \<union> y\<^isub>n, (y'\<^isub>1,\<xi>,y'\<^isub>m))"} |
1367 \begin{center} |
1372 \end{center}\\ |
1368 @{text "x\<^isub>i \<approx>bn y\<^isub>i"}\hfill |
1373 \multicolumn{2}{@ {}l}{Deep binders of the form |
1369 @{term "\<exists>p. (bn x\<^isub>i, (u\<^isub>1,\<xi>,u\<^isub>m)) \<approx>gen R fv p (bn y\<^isub>i, (v\<^isub>1,\<xi>,v\<^isub>m))"} |
1374 \isacommand{bind\_set}~@{text "bn x"}~\isacommand{in}~@{text "x'\<^isub>1\<dots>x'\<^isub>m"}:}\\ |
1370 \end{center} |
1375 $\bullet$ & Assume the bodies @{text "x'\<^isub>1\<dots>x'\<^isub>m"} are of type @{text "ty\<^isub>1\<dots>ty\<^isub>m"}, |
1371 |
1376 @{text "R"} is @{text "\<approx>ty\<^isub>1 \<otimes> ... \<otimes> \<approx>ty\<^isub>m"} and @{text fv} is |
1372 \noindent |
1377 @{text "fv_ty\<^isub>1 \<oplus> ... \<oplus> fv_ty\<^isub>m"}, then for recursive deep binders |
1373 where @{text R} is @{text "\<approx>ty\<^isub>1 \<otimes> ... \<otimes> \<approx>ty\<^isub>m"} and @{text fv} is |
1378 \begin{center} |
1374 @{text "fv_ty\<^isub>1 \<oplus> ... \<oplus> fv_ty\<^isub>m"}. Similarly for the other binding modes. |
1379 @{term "\<exists>p. (bn x, (x'\<^isub>1,\<xi>,x'\<^isub>m)) \<approx>gen R fv p (bn y, (y'\<^isub>1,\<xi>,y'\<^isub>m))"} |
1375 |
1380 \end{center}\\ |
1376 \item The @{text "(x\<^isub>i, y\<^isub>i)"} is a deep recursive binders with type @{text "ty"} |
1381 $\bullet$ & for non-recursive binders we generate in addition @{text "x \<approx>bn y"}\\ |
1377 and @{text bn} is the corresponding binding function. We assume |
1382 \end{tabular}} |
1378 @{text "(u\<^isub>1, v\<^isub>1),\<dots>,(u\<^isub>m, v\<^isub>m)"} are the corresponding bodies with types @{text "ty\<^isub>1,\<dots>, ty\<^isub>m"}. |
1383 \end{equation} |
1379 For the binding mode \isacommand{bind\_set} we generate the premise |
1384 |
1380 % |
1385 \noindent |
1381 \begin{center} |
1386 Similarly for the other binding modes. |
1382 @{term "\<exists>p. (bn x\<^isub>i, (x\<^isub>i, u\<^isub>1,\<xi>,u\<^isub>m)) \<approx>gen R fv p (bn y\<^isub>i, (y\<^isub>i, v\<^isub>1,\<xi>,v\<^isub>m))"} |
1387 From this definition it is clear why we have to impose the restriction |
1383 \end{center} |
1388 of excluding overlapping deep binders, as these would need to be translated into separate |
1384 |
|
1385 \noindent |
|
1386 where @{text R} is @{text "\<approx>ty \<otimes> \<approx>ty\<^isub>1 \<otimes> ... \<otimes> \<approx>ty\<^isub>m"} and @{text fv} is |
|
1387 @{text "fv_ty \<oplus> fv_ty\<^isub>1 \<oplus> ... \<oplus> fv_ty\<^isub>m"}. Similarly for the other modes. |
|
1388 \end{itemize} |
|
1389 |
|
1390 \noindent |
|
1391 From this definition it is clear why we can only support one binding mode per binder |
|
1392 and body, as we cannot mix the relations $\approx_{\textit{set}}$, $\approx_{\textit{list}}$ |
|
1393 and $\approx_{\textit{res}}$. It is also clear why we have to impose the restriction |
|
1394 of excluding overlapping binders, as these would need to be translated into separate |
|
1395 abstractions. |
1389 abstractions. |
1396 |
1390 |
1397 |
|
1398 The only cases that are not covered by the rules above are the cases where @{text "(x\<^isub>i, y\<^isub>i)"} is |
|
1399 neither a binder nor a body in a binding clause. Then we just generate @{text "x\<^isub>i \<approx>ty y\<^isub>i"} provided |
|
1400 the type of @{text "x\<^isub>i"} and @{text "y\<^isub>i"} is @{text ty} and the arguments are |
|
1401 recursive arguments of the term-constructor. If they are non-recursive arguments, |
|
1402 then we generate the premise @{text "x\<^isub>i = y\<^isub>i"}. |
|
1403 |
1391 |
1404 |
1392 |
1405 The alpha-equivalence relations @{text "\<approx>bn\<^isub>j"} for binding functions |
1393 The alpha-equivalence relations @{text "\<approx>bn\<^isub>j"} for binding functions |
1406 are similar. We again have conclusions of the form \mbox{@{text "C x\<^isub>1 \<dots> x\<^isub>n \<approx>bn C y\<^isub>1 \<dots> y\<^isub>n"}} |
1394 are similar. We again have conclusions of the form \mbox{@{text "C x\<^isub>1 \<dots> x\<^isub>n \<approx>bn C y\<^isub>1 \<dots> y\<^isub>n"}} |
1407 and need to generate appropriate premises. We generate first premises according to the first three |
1395 and need to generate appropriate premises. We generate first premises according to the first three |