22 alpha_res ("_ \<approx>\<^raw:\raisebox{-1pt}{\makebox[0mm][l]{$\,_{\textit{res}}$}}>\<^bsup>_,_,_\<^esup> _") and |
22 alpha_res ("_ \<approx>\<^raw:\raisebox{-1pt}{\makebox[0mm][l]{$\,_{\textit{res}}$}}>\<^bsup>_,_,_\<^esup> _") and |
23 abs_set ("_ \<approx>\<^raw:{$\,_{\textit{abs\_set}}$}> _") and |
23 abs_set ("_ \<approx>\<^raw:{$\,_{\textit{abs\_set}}$}> _") and |
24 fv ("fv'(_')" [100] 100) and |
24 fv ("fv'(_')" [100] 100) and |
25 equal ("=") and |
25 equal ("=") and |
26 alpha_abs ("_ \<approx>\<^raw:{$\,_{\textit{abs\_set}}$}> _") and |
26 alpha_abs ("_ \<approx>\<^raw:{$\,_{\textit{abs\_set}}$}> _") and |
27 Abs ("[_]\<^raw:$\!$>\<^bsub>set\<^esub>._") and |
27 Abs ("[_]\<^raw:$\!$>\<^bsub>set\<^esub>._" [20, 101] 999) and |
28 Abs_lst ("[_]\<^raw:$\!$>\<^bsub>list\<^esub>._") and |
28 Abs_lst ("[_]\<^raw:$\!$>\<^bsub>list\<^esub>._") and |
29 Abs_res ("[_]\<^raw:$\!$>\<^bsub>res\<^esub>._") and |
29 Abs_res ("[_]\<^raw:$\!$>\<^bsub>res\<^esub>._") and |
30 Cons ("_::_" [78,77] 73) |
30 Cons ("_::_" [78,77] 73) and |
|
31 supp_gen ("aux _" [1000] 100) |
31 (*>*) |
32 (*>*) |
32 |
33 |
33 |
34 |
34 section {* Introduction *} |
35 section {* Introduction *} |
35 |
36 |
167 \begin{center} |
168 \begin{center} |
168 @{text "\<LET> [x\<^isub>1,\<dots>,x\<^isub>n].s [t\<^isub>1,\<dots>,t\<^isub>n]"} |
169 @{text "\<LET> [x\<^isub>1,\<dots>,x\<^isub>n].s [t\<^isub>1,\<dots>,t\<^isub>n]"} |
169 \end{center} |
170 \end{center} |
170 |
171 |
171 \noindent |
172 \noindent |
172 where the notation @{text "[_]._"} indicates that the @{text "x\<^isub>i"} |
173 where the notation @{text "[_]._"} indicates that the list of @{text "x\<^isub>i"} |
173 become bound in @{text s}. In this representation the term |
174 becomes bound in @{text s}. In this representation the term |
174 \mbox{@{text "\<LET> [x].s [t\<^isub>1, t\<^isub>2]"}} is a perfectly legal |
175 \mbox{@{text "\<LET> [x].s [t\<^isub>1, t\<^isub>2]"}} is a perfectly legal |
175 instance, but the lengths of two lists do not agree. To exclude such terms, |
176 instance, but the lengths of two lists do not agree. To exclude such terms, |
176 additional predicates about well-formed |
177 additional predicates about well-formed |
177 terms are needed in order to ensure that the two lists are of equal |
178 terms are needed in order to ensure that the two lists are of equal |
178 length. This can result into very messy reasoning (see for |
179 length. This can result into very messy reasoning (see for |
234 \begin{center} |
235 \begin{center} |
235 @{text "\<forall>{x}. x \<rightarrow> y = \<forall>{x, z}. x \<rightarrow> y"} |
236 @{text "\<forall>{x}. x \<rightarrow> y = \<forall>{x, z}. x \<rightarrow> y"} |
236 \end{center} |
237 \end{center} |
237 |
238 |
238 \noindent |
239 \noindent |
239 are not just alpha-equal, but actually \emph{equal}. As a result, we can |
240 are not just alpha-equal, but actually \emph{equal}! As a result, we can |
240 only support specifications that make sense on the level of alpha-equated |
241 only support specifications that make sense on the level of alpha-equated |
241 terms (offending specifications, which for example bind a variable according |
242 terms (offending specifications, which for example bind a variable according |
242 to a variable bound somewhere else, are not excluded by Ott, but we have |
243 to a variable bound somewhere else, are not excluded by Ott, but we have |
243 to). |
244 to). |
244 |
245 |
339 for alpha-equated terms. |
340 for alpha-equated terms. |
340 |
341 |
341 The examples we have in mind where our reasoning infrastructure will be |
342 The examples we have in mind where our reasoning infrastructure will be |
342 helpful includes the term language of System @{text "F\<^isub>C"}, also |
343 helpful includes the term language of System @{text "F\<^isub>C"}, also |
343 known as Core-Haskell (see Figure~\ref{corehas}). This term language |
344 known as Core-Haskell (see Figure~\ref{corehas}). This term language |
344 involves patterns that have lists of type- and term-variables (the |
345 involves patterns that have lists of type-, coercion- and term-variables |
345 arguments of constructors) all of which are bound in case expressions. One |
346 all of which are bound in @{text "\<CASE>"}-expressions. One |
346 difficulty is that each of these variables come with a kind or type |
347 difficulty is that each of these variables come with a kind or type |
347 annotation. Representing such binders with single binders and reasoning |
348 annotation. Representing such binders with single binders and reasoning |
348 about them in a theorem prover would be a major pain. \medskip |
349 about them in a theorem prover would be a major pain. \medskip |
349 |
350 |
350 \noindent |
351 \noindent |
409 to aid the description of what follows. |
410 to aid the description of what follows. |
410 |
411 |
411 Two central notions in the nominal |
412 Two central notions in the nominal |
412 logic work are sorted atoms and sort-respecting permutations of atoms. The |
413 logic work are sorted atoms and sort-respecting permutations of atoms. The |
413 sorts can be used to represent different kinds of variables, such as the |
414 sorts can be used to represent different kinds of variables, such as the |
414 term- and type-variables in Core-Haskell, and it is assumed that there is an |
415 term-, coercion- and type-variables in Core-Haskell, and it is assumed that there is an |
415 infinite supply of atoms for each sort. However, in order to simplify the |
416 infinite supply of atoms for each sort. However, in order to simplify the |
416 description, we shall assume in what follows that there is only one sort of |
417 description, we shall assume in what follows that there is only one sort of |
417 atoms. |
418 atoms. |
418 |
419 |
419 Permutations are bijective functions from atoms to atoms that are |
420 Permutations are bijective functions from atoms to atoms that are |
420 the identity everywhere except on a finite number of atoms. There is a |
421 the identity everywhere except on a finite number of atoms. There is a |
421 two-place permutation operation written |
422 two-place permutation operation written |
422 % |
423 % |
423 @{text[display,indent=5] "_ \<bullet> _ :: perm \<Rightarrow> \<beta> \<Rightarrow> \<beta>"} |
424 \begin{center} |
|
425 @{text "_ \<bullet> _ :: perm \<Rightarrow> \<beta> \<Rightarrow> \<beta>"} |
|
426 \end{center} |
424 |
427 |
425 \noindent |
428 \noindent |
426 in which the generic type @{text "\<beta>"} stands for the type of the object |
429 in which the generic type @{text "\<beta>"} stands for the type of the object |
427 over which the permutation |
430 over which the permutation |
428 acts. In Nominal Isabelle, the identity permutation is written as @{term "0::perm"}, |
431 acts. In Nominal Isabelle, the identity permutation is written as @{term "0::perm"}, |
429 the composition of two permutations @{term p} and @{term q} as \mbox{@{term "p + q"}}, |
432 the composition of two permutations @{term p} and @{term q} as \mbox{@{term "p + q"}}, |
430 and the inverse permutation of @{term p} as @{text "- p"}. The permutation |
433 and the inverse permutation of @{term p} as @{text "- p"}. The permutation |
431 operation is defined by induction over the type-hierarchy, for example as follows |
434 operation is defined by induction over the type-hierarchy (see \cite{HuffmanUrban10}); |
432 for products, lists, sets, functions and booleans (see \cite{HuffmanUrban10}): |
435 for example as follows for products, lists, sets, functions and booleans: |
433 % |
436 % |
434 \begin{equation} |
437 \begin{equation}\label{permute} |
435 \mbox{\begin{tabular}{@ {}cc@ {}} |
438 \mbox{\begin{tabular}{@ {}cc@ {}} |
436 \begin{tabular}{@ {}l@ {}} |
439 \begin{tabular}{@ {}l@ {}} |
437 @{thm permute_prod.simps[no_vars, THEN eq_reflection]}\\[2mm] |
440 @{thm permute_prod.simps[no_vars, THEN eq_reflection]}\\[2mm] |
438 @{thm permute_list.simps(1)[no_vars, THEN eq_reflection]}\\ |
441 @{thm permute_list.simps(1)[no_vars, THEN eq_reflection]}\\ |
439 @{thm permute_list.simps(2)[no_vars, THEN eq_reflection]}\\ |
442 @{thm permute_list.simps(2)[no_vars, THEN eq_reflection]}\\ |
445 \end{tabular} |
448 \end{tabular} |
446 \end{tabular}} |
449 \end{tabular}} |
447 \end{equation} |
450 \end{equation} |
448 |
451 |
449 \noindent |
452 \noindent |
450 Concrete permutations are build up from swappings, written as @{text "(a |
453 Concrete permutations are built up from swappings, written as \mbox{@{text "(a |
451 b)"}, which are permutations that behave as follows: |
454 b)"}}, which are permutations that behave as follows: |
452 % |
455 % |
453 @{text[display,indent=5] "(a b) = \<lambda>c. if a = c then b else if b = c then a else c"} |
456 \begin{center} |
454 |
457 @{text "(a b) = \<lambda>c. if a = c then b else if b = c then a else c"} |
|
458 \end{center} |
|
459 |
455 The most original aspect of the nominal logic work of Pitts is a general |
460 The most original aspect of the nominal logic work of Pitts is a general |
456 definition for the notion of ``the set of free variables of an object @{text |
461 definition for the notion of the ``set of free variables of an object @{text |
457 "x"}''. This notion, written @{term "supp x"}, is general in the sense that |
462 "x"}''. This notion, written @{term "supp x"}, is general in the sense that |
458 it applies not only to lambda-terms (alpha-equated or not), but also to lists, |
463 it applies not only to lambda-terms (alpha-equated or not), but also to lists, |
459 products, sets and even functions. The definition depends only on the |
464 products, sets and even functions. The definition depends only on the |
460 permutation operation and on the notion of equality defined for the type of |
465 permutation operation and on the notion of equality defined for the type of |
461 @{text x}, namely: |
466 @{text x}, namely: |
462 % |
467 % |
463 @{thm[display,indent=5] supp_def[no_vars, THEN eq_reflection]} |
468 \begin{equation}\label{suppdef} |
|
469 @{thm supp_def[no_vars, THEN eq_reflection]} |
|
470 \end{equation} |
464 |
471 |
465 \noindent |
472 \noindent |
466 There is also the derived notion for when an atom @{text a} is \emph{fresh} |
473 There is also the derived notion for when an atom @{text a} is \emph{fresh} |
467 for an @{text x}, defined as |
474 for an @{text x}, defined as |
468 % |
475 % |
469 @{thm[display,indent=5] fresh_def[no_vars]} |
476 \begin{center} |
|
477 @{thm fresh_def[no_vars]} |
|
478 \end{center} |
470 |
479 |
471 \noindent |
480 \noindent |
472 We also use for sets of atoms the abbreviation |
481 We also use for sets of atoms the abbreviation |
473 @{thm (lhs) fresh_star_def[no_vars]} defined as |
482 @{thm (lhs) fresh_star_def[no_vars]}, defined as |
474 @{thm (rhs) fresh_star_def[no_vars]}. |
483 @{thm (rhs) fresh_star_def[no_vars]}. |
475 A striking consequence of these definitions is that we can prove |
484 A striking consequence of these definitions is that we can prove |
476 without knowing anything about the structure of @{term x} that |
485 without knowing anything about the structure of @{term x} that |
477 swapping two fresh atoms, say @{text a} and @{text b}, leave |
486 swapping two fresh atoms, say @{text a} and @{text b}, leave |
478 @{text x} unchanged. |
487 @{text x} unchanged. |
480 \begin{property} |
489 \begin{property} |
481 @{thm[mode=IfThen] swap_fresh_fresh[no_vars]} |
490 @{thm[mode=IfThen] swap_fresh_fresh[no_vars]} |
482 \end{property} |
491 \end{property} |
483 |
492 |
484 \noindent |
493 \noindent |
485 While it is often clear what the support for a construction is, for |
494 While often the support of an object can be easily described, for |
486 example |
495 example\\[-6mm] |
487 % |
496 % |
488 \begin{eqnarray} |
497 \begin{eqnarray} |
|
498 @{term "supp a"} & = & @{term "{a}"}\\ |
489 @{term "supp (x, y)"} & = & @{term "supp x \<union> supp y"}\\ |
499 @{term "supp (x, y)"} & = & @{term "supp x \<union> supp y"}\\ |
490 @{term "supp []"} & = & @{term "{}"}\\ |
500 @{term "supp []"} & = & @{term "{}"}\\ |
491 @{term "supp (x#xs)"} & = & @{term "supp (x, xs)"}\\ |
501 @{term "supp (x#xs)"} & = & @{term "supp (x, xs)"}\\ |
492 @{text "supp (f x)"} & @{text "\<subseteq>"} & @{term "supp (f, x)"}\\ |
502 @{text "supp (f x)"} & @{text "\<subseteq>"} & @{term "supp (f, x)"}\label{suppfun}\\ |
493 @{term "supp b"} & = & @{term "{}"} |
503 @{term "supp b"} & = & @{term "{}"}\\ |
|
504 @{term "supp p"} & = & @{term "{a. p \<bullet> a \<noteq> a}"} |
494 \end{eqnarray} |
505 \end{eqnarray} |
495 |
506 |
496 \noindent |
507 \noindent |
497 it can sometimes be difficult to establish the support precisely, |
508 in some cases it can be difficult to establish the support precisely, and |
498 and only give an approximation (see functions above). Such approximations can |
509 only give an approximation (see the case for function applications |
499 be formalised with the notion \emph{supports}, defined as follows. |
510 above). Such approximations can be made precise with the notion |
|
511 \emph{supports}, defined as follows |
500 |
512 |
501 \begin{defn} |
513 \begin{defn} |
502 A set @{text S} \emph{supports} @{text x} if for all atoms @{text a} and @{text b} |
514 A set @{text S} \emph{supports} @{text x} if for all atoms @{text a} and @{text b} |
503 not in @{text S} we have @{term "(a \<rightleftharpoons> b) \<bullet> x = x"}. |
515 not in @{text S} we have @{term "(a \<rightleftharpoons> b) \<bullet> x = x"}. |
504 \end{defn} |
516 \end{defn} |
505 |
517 |
506 \noindent |
518 \noindent |
507 The point of this definition is that we can show: |
519 The main point of this definition is that we can show the following two properties. |
508 |
520 |
509 \begin{property} |
521 \begin{property}\label{supportsprop} |
510 {\it i)} @{thm[mode=IfThen] supp_is_subset[no_vars]} |
522 {\it i)} @{thm[mode=IfThen] supp_is_subset[no_vars]}\\ |
511 {\it ii)} @{thm supp_supports[no_vars]}. |
523 {\it ii)} @{thm supp_supports[no_vars]}. |
512 \end{property} |
524 \end{property} |
513 |
525 |
514 \noindent |
|
515 Another important notion in the nominal logic work is \emph{equivariance}. |
526 Another important notion in the nominal logic work is \emph{equivariance}. |
516 For a function @{text f}, lets say of type @{text "\<alpha> \<Rightarrow> \<beta>"}, to be equivariant |
527 For a function @{text f}, say of type @{text "\<alpha> \<Rightarrow> \<beta>"}, to be equivariant |
517 means that every permutation leaves @{text f} unchanged, or equivalently that |
528 requires that every permutation leaves @{text f} unchanged, or equivalently that |
518 a permutation applied to an application @{text "f x"} can be moved to its |
529 a permutation applied to the application @{text "f x"} can be moved to its |
519 arguments. That is |
530 arguments. That is |
520 |
531 % |
521 \begin{center} |
532 \begin{equation}\label{equivariance} |
522 @{text "\<forall>p. p \<bullet> f = f"} \hspace{5mm} |
533 @{text "\<forall>p. p \<bullet> f = f"} \;\;if and only if\;\; |
523 @{text "\<forall>p. p \<bullet> (f x) = f (p \<bullet> x)"} |
534 @{text "\<forall>p. p \<bullet> (f x) = f (p \<bullet> x)"} |
524 \end{center} |
535 \end{equation} |
525 |
536 |
526 \noindent |
537 \noindent |
527 From the first equation we can be easily deduce that an equivariant function has |
538 From the first equation and the definition of support shown in \eqref{suppdef}, |
528 empty support. |
539 we can be easily deduce that an equivariant function has empty support. |
529 |
540 |
530 %\begin{property} |
541 In the next section we use @{text "supp"} and permutations for characterising |
531 %@{thm[mode=IfThen] at_set_avoiding[no_vars]} |
542 alpha-equivalence in the presence of multiple binders. |
532 %\end{property} |
543 |
533 |
|
534 *} |
544 *} |
535 |
545 |
536 |
546 |
537 section {* General Binders\label{sec:binders} *} |
547 section {* General Binders\label{sec:binders} *} |
538 |
548 |
717 indicating that a set or list is abstracted in @{text x}. We will call the types |
727 indicating that a set or list is abstracted in @{text x}. We will call the types |
718 \emph{abstraction types} and their elements \emph{abstractions}. The important |
728 \emph{abstraction types} and their elements \emph{abstractions}. The important |
719 property we need is a characterisation for the support of abstractions, namely |
729 property we need is a characterisation for the support of abstractions, namely |
720 |
730 |
721 \begin{thm}[Support of Abstractions]\label{suppabs} |
731 \begin{thm}[Support of Abstractions]\label{suppabs} |
722 Assuming @{text x} has finite support, then |
732 Assuming @{text x} has finite support, then\\[-6mm] |
723 \begin{center} |
733 \begin{center} |
724 \begin{tabular}{l@ {\hspace{2mm}}c@ {\hspace{2mm}}l} |
734 \begin{tabular}{l@ {\hspace{2mm}}c@ {\hspace{2mm}}l} |
725 @{thm (lhs) supp_abs(1)[no_vars]} & $=$ & @{thm (rhs) supp_abs(1)[no_vars]}\\ |
735 @{thm (lhs) supp_abs(1)[no_vars]} & $=$ & @{thm (rhs) supp_abs(1)[no_vars]}\\ |
726 @{thm (lhs) supp_abs(2)[no_vars]} & $=$ & @{thm (rhs) supp_abs(2)[no_vars]}\\ |
736 @{thm (lhs) supp_abs(2)[no_vars]} & $=$ & @{thm (rhs) supp_abs(2)[no_vars]}\\ |
727 @{thm (lhs) supp_abs(3)[no_vars]} & $=$ & @{thm (rhs) supp_abs(3)[no_vars]} |
737 @{thm (lhs) supp_abs(3)[no_vars]} & $=$ & @{thm (rhs) supp_abs(3)[no_vars]} |
728 \end{tabular} |
738 \end{tabular} |
729 \end{center} |
739 \end{center} |
730 \end{thm} |
740 \end{thm} |
731 |
741 |
732 \noindent |
742 \noindent |
733 We will only show in the rest of the section the first equation, as the others |
743 We will only show the first equation as the others |
734 follow similar arguments. By definition of the abstraction type @{text "abs_set"} |
744 follow similar arguments. By definition of the abstraction type @{text "abs_set"} |
735 we have |
745 we have |
736 % |
746 % |
737 \begin{equation}\label{abseqiff} |
747 \begin{equation}\label{abseqiff} |
738 @{thm (lhs) abs_eq_iff(1)[where bs="as" and cs="bs", no_vars]} \;\text{if and only if}\; |
748 @{thm (lhs) abs_eq_iff(1)[where bs="as" and cs="bs", no_vars]} \;\;\text{if and only if}\;\; |
739 @{thm (rhs) abs_eq_iff(1)[where bs="as" and cs="bs", no_vars]} |
749 @{thm (rhs) abs_eq_iff(1)[where bs="as" and cs="bs", no_vars]} |
740 \end{equation} |
750 \end{equation} |
741 |
751 |
742 \noindent |
752 \noindent |
743 With this, we can show the following lemma about swapping two atoms (the permutation |
753 and also |
744 operation for abstractions is the one lifted for pairs).\footnote{metion this in the nominal |
754 % |
745 logic section} |
755 \begin{equation} |
746 |
756 @{thm permute_Abs[no_vars]} |
|
757 \end{equation} |
|
758 |
|
759 \noindent |
|
760 The last fact derives from the definition of permutations acting on pairs |
|
761 (see \eqref{permute}) and alpha-equivalence being equivariant (see Lemma~\ref{alphaeq}). |
|
762 |
|
763 With these two facts at our disposal, we can show the following lemma |
|
764 about swapping two atoms. |
|
765 |
747 \begin{lemma} |
766 \begin{lemma} |
748 @{thm[mode=IfThen] abs_swap1(1)[no_vars]} |
767 @{thm[mode=IfThen] abs_swap1(1)[no_vars]} |
749 \end{lemma} |
768 \end{lemma} |
750 |
769 |
751 \begin{proof} |
770 \begin{proof} |
761 \begin{equation}\label{halfone} |
780 \begin{equation}\label{halfone} |
762 @{thm abs_supports(1)[no_vars]} |
781 @{thm abs_supports(1)[no_vars]} |
763 \end{equation} |
782 \end{equation} |
764 |
783 |
765 \noindent |
784 \noindent |
766 which with \ref{} gives us one half of Thm~\ref{suppabs}. The other half is |
785 which with Property~\ref{supportsprop} gives us one half of |
767 a bit more involved. We first define an auxiliary function |
786 Thm~\ref{suppabs}. The other half is a bit more involved. For this we use a |
768 % |
787 trick from \cite{Pitts04} and first define an auxiliary function |
769 \begin{center} |
788 % |
770 @{thm supp_res.simps[THEN eq_reflection, no_vars]} |
789 \begin{center} |
771 \end{center} |
790 @{thm supp_gen.simps[THEN eq_reflection, no_vars]} |
772 |
791 \end{center} |
773 |
792 |
774 \begin{lemma} |
793 \noindent |
775 $supp ([as]set. x) = supp x - as$ |
794 Using the second equation in \eqref{equivariance}, we can show that |
776 \end{lemma} |
795 @{term "supp_gen"} is equivariant and therefore has empty support. This |
777 |
796 in turn means |
778 \noindent |
797 % |
779 The point of these general lemmas about pairs is that we can define and prove properties |
798 \begin{center} |
780 about them conveniently on the Isabelle level, and in addition can use them in what |
799 @{thm (prem 1) aux_fresh(1)[where bs="as", no_vars]} |
781 follows next when we have to deal with specific instances of term-specification. |
800 \;\;implies\;\; |
|
801 @{thm (concl) aux_fresh(1)[where bs="as", no_vars]} |
|
802 \end{center} |
|
803 |
|
804 \noindent |
|
805 using \eqref{suppfun}. Since @{term "supp x"} is by definition equal |
|
806 to @{term "{a. \<not> a \<sharp> x}"} we can establish that |
|
807 % |
|
808 \begin{equation}\label{halftwo} |
|
809 @{thm (concl) supp_abs_subset1(1)[no_vars]} |
|
810 \end{equation} |
|
811 |
|
812 \noindent |
|
813 provided @{text x} has finite support (the precondition we need in order to show |
|
814 that for a finite set of atoms, we have @{thm (concl) supp_finite_atom_set[where S="bs", no_vars]}). |
|
815 |
|
816 Finally taking \eqref{halfone} and \eqref{halftwo} provides us with a proof |
|
817 of Theorem~\ref{suppabs}. The point of these general lemmas about abstractions is that we |
|
818 can define and prove properties about them conveniently on the Isabelle/HOL level, |
|
819 and in addition can use them in what |
|
820 follows next when we have to deal with binding in specifications of term-calculi. |
782 *} |
821 *} |
783 |
822 |
784 section {* Alpha-Equivalence and Free Variables *} |
823 section {* Alpha-Equivalence and Free Variables *} |
785 |
824 |
786 text {* |
825 text {* |
787 Our specifications for term-calculi are heavily inspired by the existing |
826 Our choice of syntax for specifications of term-calculi is influenced by the existing |
788 datatype package of Isabelle/HOL and by the syntax of the Ott-tool |
827 datatype package of Isabelle/HOL and by the syntax of the Ott-tool |
789 \cite{ott-jfp}. A specification is a collection of (possibly mutual |
828 \cite{ott-jfp}. A specification is a collection of (possibly mutual |
790 recursive) type declarations, say @{text "ty"}$^\alpha_1$, \ldots, |
829 recursive) type declarations, say @{text "ty"}$^\alpha_1$, \ldots, |
791 @{text ty}$^\alpha_n$, and an associated collection |
830 @{text ty}$^\alpha_n$, and an associated collection |
792 of binding functions, say @{text bn}$^\alpha_1$, \ldots, @{text |
831 of binding functions, say @{text bn}$^\alpha_1$, \ldots, @{text |