531 text {* |
530 text {* |
532 Our specifications for term-calculi are heavily |
531 Our specifications for term-calculi are heavily |
533 inspired by the syntax of the Ott-tool \cite{ott-jfp}. A specification is |
532 inspired by the syntax of the Ott-tool \cite{ott-jfp}. A specification is |
534 a collection of (possibly mutual recursive) type declarations, say |
533 a collection of (possibly mutual recursive) type declarations, say |
535 $ty^\alpha_1$, $ty^\alpha_2$, \ldots $ty^\alpha_n$, and an |
534 $ty^\alpha_1$, $ty^\alpha_2$, \ldots $ty^\alpha_n$, and an |
536 associated collection of binding function declarations, say |
535 associated collection of binding functions, say |
537 $bn^\alpha_1$, \ldots $bn^\alpha_m$. The syntax in Nominal Isabelle |
536 $bn^\alpha_1$, \ldots, $bn^\alpha_m$. The syntax in Nominal Isabelle |
538 for such specifications is rougly as follows: |
537 for such specifications is rougly as follows: |
539 % |
538 % |
540 \begin{equation}\label{scheme} |
539 \begin{equation}\label{scheme} |
541 \mbox{\begin{tabular}{@ {\hspace{-9mm}}p{1.8cm}l} |
540 \mbox{\begin{tabular}{@ {\hspace{-5mm}}p{1.8cm}l} |
542 type \mbox{declaration part} & |
541 type \mbox{declaration part} & |
543 $\begin{cases} |
542 $\begin{cases} |
544 \mbox{\begin{tabular}{l} |
543 \mbox{\begin{tabular}{l} |
545 \isacommand{nominal\_datatype} $ty^\alpha_1 = \ldots$\\ |
544 \isacommand{nominal\_datatype} $ty^\alpha_1 = \ldots$\\ |
546 \isacommand{and} $ty^\alpha_2 = \ldots$\\ |
545 \isacommand{and} $ty^\alpha_2 = \ldots$\\ |
562 |
561 |
563 \noindent |
562 \noindent |
564 Every type declaration $ty^\alpha_i$ consists of a collection of |
563 Every type declaration $ty^\alpha_i$ consists of a collection of |
565 term-constructors, each of which comes with a list of labelled |
564 term-constructors, each of which comes with a list of labelled |
566 types that stand for the types of the arguments of the term-constructor. |
565 types that stand for the types of the arguments of the term-constructor. |
567 For example for a term-constructor $C^\alpha$ we might have |
566 For example a term-constructor $C^\alpha$ might have |
568 |
567 |
569 \begin{center} |
568 \begin{center} |
570 $C^\alpha\;label_1\!::\!ty'_1\;\ldots label_l\!::\!ty'_l\;\;\textit{binding\_clauses}$ |
569 $C^\alpha\;label_1\!::\!ty'_1\;\ldots label_l\!::\!ty'_l\;\;\textit{binding\_clauses}$ |
571 \end{center} |
570 \end{center} |
572 |
571 |
573 \noindent |
572 \noindent |
574 whereby some of the $ty'_k$ (or their type components) are contained in the |
573 whereby some of the $ty'_k$ (or their components) are contained in the collection |
575 set of $ty^\alpha_i$ |
574 of $ty^\alpha_i$ declared in \eqref{scheme}. In this case we will call the |
576 declared in \eqref{scheme}. In this case we will call |
575 corresponding argument a \emph{recursive argument}. The labels annotated on |
577 the corresponding argument a \emph{recursive argument}. The labels |
576 the types are optional and can be used in the (possibly empty) list of |
578 annotated on the types are optional and can be used in the (possibly empty) |
577 \emph{binding clauses}. These clauses indicate the binders and the scope of |
579 list of \emph{binding clauses}. These clauses indicate the binders and the |
578 the binders in a term-constructor. They come in three \emph{modes} |
580 scope of the binders in a term-constructor. They come in three \emph{modes} |
579 |
581 |
580 |
582 \begin{center} |
581 \begin{center} |
583 \begin{tabular}{l} |
582 \begin{tabular}{l} |
584 \isacommand{bind}\; {\it binders}\; \isacommand{in}\; {\it label}\\ |
583 \isacommand{bind}\; {\it binders}\; \isacommand{in}\; {\it label}\\ |
585 \isacommand{bind\_set}\; {\it binders}\; \isacommand{in}\; {\it label}\\ |
584 \isacommand{bind\_set}\; {\it binders}\; \isacommand{in}\; {\it label}\\ |
586 \isacommand{bind\_res}\; {\it binders}\; \isacommand{in}\; {\it label}\\ |
585 \isacommand{bind\_res}\; {\it binders}\; \isacommand{in}\; {\it label}\\ |
587 \end{tabular} |
586 \end{tabular} |
588 \end{center} |
587 \end{center} |
589 |
588 |
590 \noindent |
589 \noindent |
591 The first mode is for binding lists of atoms (the order matters); the second is for sets |
590 The first mode is for binding lists of atoms (the order of binders matters); the second is for sets |
592 of binders (the order does not matter, but cardinality does) and the last is for |
591 of binders (the order does not matter, but cardinality does) and the last is for |
593 sets of binders (with vacuous binders preserving alpha-equivalence). |
592 sets of binders (with vacuous binders preserving alpha-equivalence). |
594 |
593 |
595 In addition we distinguish between \emph{shallow} binders and \emph{deep} |
594 In addition we distinguish between \emph{shallow} binders and \emph{deep} |
596 binders. Shallow binders are of the form \isacommand{bind}\; {\it label}\; |
595 binders. Shallow binders are of the form \isacommand{bind}\; {\it label}\; |
597 \isacommand{in}\; {\it another\_label} (similar for the other two modes). The |
596 \isacommand{in}\; {\it another\_label} (similar for the other two modes). The |
598 restriction we impose on shallow binders is that the {\it label} must either |
597 restriction we impose on shallow binders is that the {\it label} must either |
599 refer to a type that is an atom type or to a type that is a finite set or |
598 refer to a type that is an atom type or to a type that is a finite set or |
600 list of an atom type. For example the specifications of lambda-terms, where |
599 list of an atom type. For example the specifications for lambda-terms, where |
601 a single name is bound, and type-schemes, where a finite set of names is |
600 a single name is bound, and type-schemes, where a finite set of names is |
602 bound, use shallow binders (the type \emph{name} is an atom type): |
601 bound, use shallow binders (the type \emph{name} is an atom type): |
603 |
602 |
604 \begin{center} |
603 \begin{center} |
605 \begin{tabular}{@ {}cc@ {}} |
604 \begin{tabular}{@ {}cc@ {}} |
654 \hspace{5mm}\phantom{$\mid$} Var\;{\it name}\\ |
653 \hspace{5mm}\phantom{$\mid$} Var\;{\it name}\\ |
655 \hspace{5mm}$\mid$ App\;{\it trm}\;{\it trm}\\ |
654 \hspace{5mm}$\mid$ App\;{\it trm}\;{\it trm}\\ |
656 \hspace{5mm}$\mid$ Lam\;{\it x::name}\;{\it t::trm} |
655 \hspace{5mm}$\mid$ Lam\;{\it x::name}\;{\it t::trm} |
657 \;\;\isacommand{bind} {\it x} \isacommand{in} {\it t}\\ |
656 \;\;\isacommand{bind} {\it x} \isacommand{in} {\it t}\\ |
658 \hspace{5mm}$\mid$ Let\;{\it p::pat}\;{\it trm}\; {\it t::trm} |
657 \hspace{5mm}$\mid$ Let\;{\it p::pat}\;{\it trm}\; {\it t::trm} |
659 \;\;\isacommand{bind\_set} {\it bn(p)} \isacommand{in} {\it t}\\ |
658 \;\;\isacommand{bind} {\it bn(p)} \isacommand{in} {\it t}\\ |
660 \isacommand{and} {\it pat} =\\ |
659 \isacommand{and} {\it pat} =\\ |
661 \hspace{5mm}\phantom{$\mid$} PNo\\ |
660 \hspace{5mm}\phantom{$\mid$} PNo\\ |
662 \hspace{5mm}$\mid$ PVr\;{\it name}\\ |
661 \hspace{5mm}$\mid$ PVr\;{\it name}\\ |
663 \hspace{5mm}$\mid$ PPr\;{\it pat}\;{\it pat}\\ |
662 \hspace{5mm}$\mid$ PPr\;{\it pat}\;{\it pat}\\ |
664 \isacommand{with} {\it bn::pat $\Rightarrow$ atom set}\\ |
663 \isacommand{with} {\it bn::pat $\Rightarrow$ atom list}\\ |
665 \isacommand{where} $bn(\textrm{PNil}) = \varnothing$\\ |
664 \isacommand{where} $bn(\textrm{PNil}) = []$\\ |
666 \hspace{5mm}$\mid$ $bn(\textrm{PVar}\;x) = \{atom\; x\}$\\ |
665 \hspace{5mm}$\mid$ $bn(\textrm{PVar}\;x) = [atom\; x]$\\ |
667 \hspace{5mm}$\mid$ $bn(\textrm{PPrd}\;p_1\;p_2) = bn(p_1) \cup bn(p_2)$\\ |
666 \hspace{5mm}$\mid$ $bn(\textrm{PPrd}\;p_1\;p_2) = bn(p_1)\; @\;bn(p_2)$\\ |
668 \end{tabular} |
667 \end{tabular} |
669 \end{center} |
668 \end{center} |
670 |
669 |
671 \noindent |
670 \noindent |
672 In this specification the function $atom$ coerces a name into the generic |
671 In this specification the function $atom$ coerces a name into the generic |
709 \end{center} |
708 \end{center} |
710 |
709 |
711 \noindent |
710 \noindent |
712 since there is no overlap of binders. |
711 since there is no overlap of binders. |
713 |
712 |
714 Now the question is how we can turn specifications into actual type |
713 Let us come back one more time to the specification of simultaneous lets. |
|
714 A specification for them looks as follows: |
|
715 |
|
716 \begin{center} |
|
717 \begin{tabular}{l} |
|
718 \isacommand{nominal\_datatype} {\it trm} =\\ |
|
719 \hspace{5mm}\phantom{$\mid$}\ldots\\ |
|
720 \hspace{5mm}$\mid$ Let\;{\it a::assn}\; {\it t::trm} |
|
721 \;\;\isacommand{bind} {\it bn(a)} \isacommand{in} {\it t}\\ |
|
722 \isacommand{and} {\it assn} =\\ |
|
723 \hspace{5mm}\phantom{$\mid$} ANil\\ |
|
724 \hspace{5mm}$\mid$ ACons\;{\it name}\;{\it trm}\;{\it assn}\\ |
|
725 \isacommand{with} {\it bn::assn $\Rightarrow$ atom list}\\ |
|
726 \isacommand{where} $bn(\textrm{ANil}) = []$\\ |
|
727 \hspace{5mm}$\mid$ $bn(\textrm{ACons}\;x\;t\;a) = [atom\; x]\; @\; bn(a)$\\ |
|
728 \end{tabular} |
|
729 \end{center} |
|
730 |
|
731 \noindent |
|
732 The intention with this specification is to bind all variables |
|
733 from the assignments inside the body @{text t}. However one might |
|
734 like to consider the variant where the variables are not just |
|
735 bound in @{term t}, but also in the assignments themselves. In |
|
736 this case we need to specify |
|
737 |
|
738 \begin{center} |
|
739 \begin{tabular}{l} |
|
740 Let\_rec\;{\it a::assn}\; {\it t::trm} |
|
741 \;\;\isacommand{bind} {\it bn(a)} \isacommand{in} {\it t}, |
|
742 \isacommand{bind} {\it bn(a)} \isacommand{in} {\it a}\\ |
|
743 \end{tabular} |
|
744 \end{center} |
|
745 |
|
746 \noindent |
|
747 where we bind also in @{text a} all the atoms @{text bn} returns. In this |
|
748 case we will say the binder is a \emph{recursive binder}. |
|
749 |
|
750 Having dealt with all syntax matters, the problem now is how we can turn |
|
751 specifications into actual type |
715 definitions in Isabelle/HOL and then establish a reasoning infrastructure |
752 definitions in Isabelle/HOL and then establish a reasoning infrastructure |
716 for them? Because of the problem Pottier and Cheney pointed out, we cannot |
753 for them. Because of the problem Pottier and Cheney pointed out, we cannot |
717 in general re-arrange arguments of term-constructors so that binders and |
754 in general re-arrange arguments of term-constructors so that binders and |
718 their scopes next to each other, an then use the type constructors |
755 their bodies next to each other, an then use the type constructors |
719 @{text "abs_set"}, @{text "abs_res"} and @{text "abs_list"}. Therefore |
756 @{text "abs_set"}, @{text "abs_res"} and @{text "abs_list"} from Section |
|
757 \ref{sec:binders}. Therefore |
720 we will first extract datatype definitions from the specification and |
758 we will first extract datatype definitions from the specification and |
721 then define an alpha-equiavlence relation over them. |
759 then define an alpha-equiavlence relation over them. |
722 |
760 |
723 The datatype definition can be obtained by just stripping of the |
761 The datatype definition can be obtained by just stripping of the |
724 binding clauses and the labels on the types. We also have to invent |
762 binding clauses and the labels on the types. We also have to invent |
725 new names for the types, $ty^\alpha$ and term-constructors $C^\alpha$ |
763 new names for the types, $ty^\alpha$ and term-constructors $C^\alpha$ |
726 given by user. We just use an affix: |
764 given by user. We just use an affix like |
727 |
765 |
728 \begin{center} |
766 \begin{center} |
729 $ty^\alpha \mapsto ty\_raw \qquad C^\alpha \mapsto C\_raw$ |
767 $ty^\alpha \mapsto ty\_raw \qquad C^\alpha \mapsto C\_raw$ |
730 \end{center} |
768 \end{center} |
731 |
769 |
732 \noindent |
770 \noindent |
733 This definition can be made, provided the usual conditions hold: the |
771 The datatype definition can be made, provided the usual conditions hold: |
734 types must be non-empty and the types in the term-constructors need to |
772 the datatypes must be non-empty and they must only occur in positive |
735 be, what is called, positive position (see \cite{}). We then take the binding |
773 position (see \cite{}). We then consider the user-specified binding |
736 functions and define them by primitive recursion over the raw datatypes. |
774 functions and define them by primitive recursion over the raw datatypes. |
737 binding function. |
775 |
738 |
776 The first non-trivial step we have to generate free-variable |
739 The first non-trivial step is to read off from the specification free-variable |
777 functions from the specifications. The basic idea is to collect |
740 functions. There are two kinds: free-variable functions corresponding to types, |
778 all atoms that are not bound, but because of the rather complicated |
741 written $\fv\_ty$, and free-variable functions corresponding to binding functions, |
779 binding mechanisms the details are somewhat involved. |
742 written $\fv\_bn$. They have to be defined at the same time since there can |
780 There are two kinds of free-variable functions: one corresponds to types, |
743 be interdependencies. Given a term-constructor $C\_raw\;ty_1 \ldots ty_n$ and some |
781 written $\fv\_ty$, and the other corresponds to binding functions, |
744 binding clauses, the function $\fv (C\_raw\;x_1 \ldots x_n)$ will be the union |
782 written $\fv\_bn$. They have to be defined at the same time, since there can |
745 of the values generated for each argument, say $x_i$, as follows: |
783 be dependencies between them. |
746 |
784 |
747 \begin{center} |
785 Given a term-constructor $C\_raw\;ty_1 \ldots ty_n$, of type $ty$ together with |
748 \begin{tabular}{cp{8cm}} |
786 some binding clauses, the function $\fv\_ty (C\_raw\;x_1 \ldots x_n)$ will be |
749 $\bullet$ & if it is a shallow binder, then $\varnothing$\\ |
787 the union of the values generated for each argument, say $x_i$ with type $ty_i$. |
750 $\bullet$ & if it is a deep binder, then $\fv_bn x_i$\\ |
788 By the binding clause we know whether the argument $x_i$ is a shallow or deep |
751 $\bullet$ & if |
789 binder and in the latter case also whether it is a recursive or non-recursive |
752 \end{tabular} |
790 of a binder. In these cases we return as value: |
753 \end{center} |
791 |
754 |
792 \begin{center} |
755 |
793 \begin{tabular}{cp{7cm}} |
|
794 $\bullet$ & @{term "{}"} provided @{text "x\<^isub>i"} is a shallow binder\\ |
|
795 $\bullet$ & @{text "fv_bn_ty\<^isub>i x\<^isub>i"} provided @{text "x\<^isub>i"} is a deep non-recursive binder\\ |
|
796 $\bullet$ & @{text "fv_ty\<^isub>i x\<^isub>i - bn_ty\<^isub>i x\<^isub>i"} provided @{text "x\<^isub>i"} is a deep recursive binder\\ |
|
797 \end{tabular} |
|
798 \end{center} |
|
799 |
|
800 \noindent |
|
801 The binding clause will also give us whether the argument @{term "x\<^isub>i"} is |
|
802 a body of one or more abstractions. There are two cases: either the |
|
803 corresponding binders are all shallow or there is a single deep binder. |
|
804 In the former case we build the union of all shallow binders; in the |
|
805 later case we just take set or list of atoms the specified binding |
|
806 function returns. Below use @{text "bnds"} to stand for them. |
|
807 |
|
808 \begin{center} |
|
809 \begin{tabular}{cp{7cm}} |
|
810 $\bullet$ & @{text "{atom x\<^isub>i} - bnds"} provided @{term "x\<^isub>i"} is an atom\\ |
|
811 $\bullet$ & @{text "(atoms x\<^isub>i) - bnds"} provided @{term "x\<^isub>i"} is a set of atoms\\ |
|
812 $\bullet$ & @{text "(atoml x\<^isub>i) - bnds"} provided @{term "x\<^isub>i"} is a list of atoms\\ |
|
813 $\bullet$ & @{text "(fv_ty\<^isub>i x\<^isub>i) - bnds"} provided @{term "ty\<^isub>i"} is a nominal datatype\\ |
|
814 $\bullet$ & @{term "{}"} otherwise |
|
815 \end{tabular} |
|
816 \end{center} |
|
817 |
|
818 \noindent |
|
819 If the argument is neither a binder, nor a body, then it is defined as |
|
820 the four clauses above, except that @{text "bnds"} is empty. i.e.~no atoms |
|
821 are abstracted. |
756 |
822 |
757 *} |
823 *} |
758 |
824 |
759 |
825 |
760 |
826 |