Pearl-jv/Paper.thy
changeset 2740 a9e63abf3feb
parent 2736 61d30863e5d1
child 2742 f1192e3474e0
equal deleted inserted replaced
2736:61d30863e5d1 2740:a9e63abf3feb
    42 
    42 
    43 section {* Introduction *}
    43 section {* Introduction *}
    44 
    44 
    45 text {*
    45 text {*
    46   Nominal Isabelle provides a proving infratructure for convenient reasoning
    46   Nominal Isabelle provides a proving infratructure for convenient reasoning
    47   about programming language calculi involving binders, such as lambda abstractions or
    47   about syntax involving binders, such as lambda terms or type schemes:
    48   quantifications in type schemes:
    48 
    49 
    49   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
    50   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
    50   @{text "\<lambda>x. t       \<forall>{x\<^isub>1,\<dots>, x\<^isub>n}. \<tau>"}
    51   @{text "\<lambda>x. t       \<forall>{x\<^isub>1,\<dots>,x\<^isub>n}. \<tau>"}
       
    52   \hfill\numbered{atomperm}
    51   \hfill\numbered{atomperm}
    53   \end{isabelle}
    52   \end{isabelle}
    54   
    53   
    55   \noindent
    54   \noindent
    56   At its core Nominal Isabelle is based on the nominal logic work by Pitts at
    55   At its core Nominal Isabelle is based on the nominal logic work by Pitts at
    57   al \cite{GabbayPitts02,Pitts03}, whose most basic notion is a
    56   al \cite{GabbayPitts02,Pitts03}, whose most basic notion is a
    58   sort-respecting permutation operation defined over a countably infinite
    57   sort-respecting permutation operation defined over a countably infinite
    59   collection of sorted atoms. The nominal logic work has been starting
    58   collection of sorted atoms. The atoms are used for representing variable names
    60   point for a number of formalisations, most notable Norrish \cite{norrish04} 
    59   that might be bound or free. Multiple sorts are necessary for being able to
    61   in HOL4, Aydemir et al \cite{AydemirBohannonWeirich07} in Coq and our own 
    60   represent different kinds of variables. For example, in the language Mini-ML
    62   work in Isabelle/HOL.
    61   there are bound term variables in lambda abstractions and bound type variables in
    63 
    62   type schemes. In order to be able to separate them, each kind of variables needs to be
    64   
    63   represented by a different sort of atoms. 
       
    64 
       
    65   The nominal logic work has been the starting point for a number of proving
       
    66   infrastructures, most notable by Norrish \cite{norrish04} in HOL4, by
       
    67   Aydemir et al \cite{AydemirBohannonWeirich07} in Coq and teh work by Urban
       
    68   and Berghofer in Isabelle/HOL \cite{Urban08}. Its key attraction is a very
       
    69   general notion, called \emph{support}, for the `set of free variables, or
       
    70   atoms' of an object that applies not just to lambda terms and type schemes,
       
    71   but also to sets, products, lists and even functions. The notion of support
       
    72   is derived from the permutation operation defined over atoms. This
       
    73   permutation operation, written @{text "_ \<bullet> _"}, has proved to be very
       
    74   convenient for reasoning about syntax, in comparison to, say, arbitrary
       
    75   renaming substitutions of atoms. The reason is that permutations are
       
    76   bijective renamings of atoms and thus they can be easily `undone'---namely
       
    77   by applying the inverse permutation. A corresponding inverse substitution 
       
    78   might not exist in general, since renaming substitutions are only injective.  
       
    79   Permutations also preserve many constructions when reasoning about syntax. 
       
    80   For example validity of a typing context is preserved under permutations. 
       
    81   Suppose a typing context @{text "\<Gamma>"} of the form
       
    82 
       
    83   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
       
    84   @{text "x\<^isub>1:\<tau>\<^isub>1, \<dots>, x\<^isub>n:\<tau>\<^isub>n"}
       
    85   \end{isabelle}
       
    86 
       
    87   \noindent
       
    88   is said to be \emph{valid} provided none of its variables, or atoms, @{text "x\<^isub>i"}
       
    89   occur twice. Then validity is preserved under
       
    90   permutations in the sense that if @{text \<Gamma>} is valid then so is @{text "\<pi> \<bullet> \<Gamma>"} for
       
    91   all permutations @{text "\<pi>"}. This is \emph{not} the case for arbitrary
       
    92   renaming substitutions, as they might identify some variables in @{text \<Gamma>}. 
       
    93   Permutations fit well with HOL's definitions. For example 
       
    94   
       
    95 
       
    96   Because
       
    97   of the good properties of permutations, we will be able to automate reasoning 
       
    98   steps determining when a construction in HOL is
       
    99   \emph{equivariant}. By equivariance we mean the property that every
       
   100   permutation leaves an object unchanged, that is @{term "\<forall>\<pi>. \<pi> \<bullet> x = x"}.
       
   101   This will often simplify arguments involving the notion of support.
       
   102 
       
   103 
       
   104   There are a number of subtle differences between the nominal logic work by Pitts 
       
   105   and the one we will present in this paper. Nominal 
       
   106 
       
   107   In the nominal logic work, the `new quantifier' plays a prominent role.
       
   108   
       
   109 
       
   110 
    65   Using a single atom type to represent atoms of different sorts and
   111   Using a single atom type to represent atoms of different sorts and
    66   representing permutations as functions are not new ideas; see
   112   representing permutations as functions are not new ideas; see
    67   \cite{GunterOsbornPopescu09} \footnote{function rep.}  The main contribution
   113   \cite{GunterOsbornPopescu09} \footnote{function rep.}  The main contribution
    68   of this paper is to show an example of how to make better theorem proving
   114   of this paper is to show an example of how to make better theorem proving
    69   tools by choosing the right level of abstraction for the underlying
   115   tools by choosing the right level of abstraction for the underlying
    72   mechanism for dealing with ``Church-style'' lambda-terms \cite{Church40} and
   118   mechanism for dealing with ``Church-style'' lambda-terms \cite{Church40} and
    73   HOL-based languages \cite{PittsHOL4} where variables and variable binding
   119   HOL-based languages \cite{PittsHOL4} where variables and variable binding
    74   depend on type annotations.
   120   depend on type annotations.
    75 
   121 
    76   The paper is organised as follows\ldots
   122   The paper is organised as follows\ldots
       
   123 
       
   124 
       
   125   Two binders
    77 *}
   126 *}
    78 
   127 
    79 section {* Sorted Atoms and Sort-Respecting Permutations *}
   128 section {* Sorted Atoms and Sort-Respecting Permutations *}
    80 
   129 
    81 text {*
   130 text {*
    82   The most basic notion in this work is a
   131   The two most basic notions in the nominal logic work are
    83   sort-respecting permutation operation defined over a countably infinite
   132   sort-respecting permutation operation defined over a countably infinite
    84   collection of sorted atoms. The atoms are used for representing variable names
   133   collection of sorted atoms. 
    85   that might be bound or free. Multiple sorts are necessary for being able to
       
    86   represent different kinds of variables. For example, in the language Mini-ML
       
    87   there are bound term variables in lambda abstractions and bound type variables in
       
    88   type schemes. In order to be able to separate them, each kind of variables needs to be
       
    89   represented by a different sort of atoms. 
       
    90 
       
    91 
       
    92   The existing nominal logic work usually leaves implicit the sorting
   134   The existing nominal logic work usually leaves implicit the sorting
    93   information for atoms and as far as we know leaves out a description of how
   135   information for atoms and as far as we know leaves out a description of how
    94   sorts are represented.  In our formalisation, we therefore have to make a
   136   sorts are represented.  In our formalisation, we therefore have to make a
    95   design decision about how to implement sorted atoms and sort-respecting
   137   design decision about how to implement sorted atoms and sort-respecting
    96   permutations. One possibility, which we described in \cite{Urban08}, is to 
   138   permutations. One possibility, which we described in \cite{Urban08}, is to
    97   have separate types for the different
   139   have separate types for the different kinds of atoms, say types @{text
    98   kinds of atoms, say types @{text "\<alpha>\<^isub>1,\<dots>,\<alpha>\<^isub>n"}. 
   140   "\<alpha>\<^isub>1,\<dots>,\<alpha>\<^isub>n"}. However, this does not blend well with the
    99 
   141   resoning infrastructure of type-classes in Isabelle/HOL (see Section ??? 
   100   In the nominal logic work of Pitts, binders and bound variables are
   142   about related work).  Therefore we use here a single unified atom type to
   101   represented by \emph{atoms}.  As stated above, we need to have different
   143   represent atoms of different sorts. A basic requirement is that there must
   102   \emph{sorts} of atoms to be able to bind different kinds of variables.  A
   144   be a countably infinite number of atoms of each sort.  This can be
   103   basic requirement is that there must be a countably infinite number of atoms
   145   implemented as the datatype
   104   of each sort.  We implement these atoms as
   146 
   105 *}
   147 *}
   106 
   148 
   107           datatype atom\<iota> = Atom\<iota> string nat
   149           datatype atom\<iota> = Atom\<iota> string nat
   108 
   150 
   109 text {*
   151 text {*
   110   \noindent
   152   \noindent
   111   whereby the string argument specifies the sort of the atom.\footnote{A
   153   whereby the string argument specifies the sort of the atom.\footnote{A
   112   similar design choice was made by Gunter et al \cite{GunterOsbornPopescu09}
   154   similar design choice was made by Gunter et al \cite{GunterOsbornPopescu09}
   113   for their variables.}  (The use of type \emph{string} is merely for
   155   for their variables.}  The use of type \emph{string} for sorts is merely for
   114   convenience; any countably infinite type would work as well.) We have an
   156   convenience; any countably infinite type would work as well. We have an
   115   auxiliary function @{text sort} that is defined as @{thm
   157   auxiliary function @{text sort} that is defined as 
   116   sort_of.simps[no_vars]}, and we clearly have for every finite set @{text X}
   158 
       
   159   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
       
   160   @{thm sort_of.simps[no_vars, THEN eq_reflection]}
       
   161   \end{isabelle}
       
   162 
       
   163   \noindent
       
   164   and we clearly have for every finite set @{text S}
   117   of atoms and every sort @{text s} the property:
   165   of atoms and every sort @{text s} the property:
   118 
   166 
   119   \begin{proposition}\label{choosefresh}
   167   \begin{proposition}\label{choosefresh}\mbox{}\\
   120   @{text "For a finite set of atoms S, there exists an atom a such that
   168   @{text "For a finite set of atoms S, there exists an atom a such that
   121   sort a = s and a \<notin> S"}.
   169   sort a = s and a \<notin> S"}.
   122   \end{proposition}
   170   \end{proposition}
   123 
   171 
   124   For implementing sort-respecting permutations, we use functions of type @{typ
   172   For implementing sort-respecting permutations, we use functions of type @{typ
   172   partial by adding the precondition @{term "sort a = sort b"},
   220   partial by adding the precondition @{term "sort a = sort b"},
   173   which would mean that in case @{text a} and @{text b} have different sorts,
   221   which would mean that in case @{text a} and @{text b} have different sorts,
   174   the value of @{text "(a b)"} is unspecified.  However, this looked like a
   222   the value of @{text "(a b)"} is unspecified.  However, this looked like a
   175   cumbersome solution, since sort-related side conditions would be required
   223   cumbersome solution, since sort-related side conditions would be required
   176   everywhere, even to unfold the definition.  It turned out to be more
   224   everywhere, even to unfold the definition.  It turned out to be more
   177   convenient to actually allow the user to state ``ill-sorted'' swappings but
   225   convenient to actually allow the user to state `ill-sorted' swappings but
   178   limit their ``damage'' by defaulting to the identity permutation in the
   226   limit their `damage' by defaulting to the identity permutation in the
   179   ill-sorted case:
   227   ill-sorted case:
   180 
   228 
   181   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   229   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   182   \begin{tabular}{@ {}rl}
   230   \begin{tabular}{@ {}rl}
   183   @{text "(a b) \<equiv>"} & @{text "if (sort a = sort b)"}\\ 
   231   @{text "(a b) \<equiv>"} & @{text "if (sort a = sort b)"}\\ 
   189   \noindent
   237   \noindent
   190   This function is bijective, the identity on all atoms except
   238   This function is bijective, the identity on all atoms except
   191   @{text a} and @{text b}, and sort respecting. Therefore it is 
   239   @{text a} and @{text b}, and sort respecting. Therefore it is 
   192   a function in @{typ perm}. 
   240   a function in @{typ perm}. 
   193 
   241 
   194   One advantage of using functions instead of lists as a representation for
   242   One advantage of using functions as a representation for
   195   permutations is that for example the swappings
   243   permutations is that for example the swappings
   196 
   244 
   197   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   245   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   198   \begin{tabular}{@ {}l}
   246   \begin{tabular}{@ {}l}
   199   @{thm swap_commute[no_vars]}\hspace{10mm}
   247   @{thm swap_commute[no_vars]}\hspace{10mm}
   200   @{text "(a a) = id"}
   248   @{text "(a a) = id"}
   201   \end{tabular}\hfill\numbered{swapeqs}
   249   \end{tabular}\hfill\numbered{swapeqs}
   202   \end{isabelle}
   250   \end{isabelle}
   203 
   251 
   204   \noindent
   252   \noindent
   205   are \emph{equal}.  We do not have to use the equivalence relation shown
   253   are \emph{equal}.  Therfore we can use for permutations HOL's built-in
   206   in~\eqref{permequ} to identify them, as we would if they had been represented
   254   principle of `replacing equals by equals in any context'. Another advantage
   207   as lists of pairs.  Another advantage of the function representation is that
   255   of the function representation is that they form a (non-commutative) group
   208   they form a (non-commutative) group provided we define
   256   provided we define
       
   257 
   209 
   258 
   210   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   259   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   211   \begin{tabular}{@ {}l}
   260   \begin{tabular}{@ {}l}
   212   @{thm zero_perm_def[no_vars, THEN eq_reflection]} \hspace{4mm}
   261   @{thm zero_perm_def[no_vars, THEN eq_reflection]} \hspace{5mm}
   213   @{thm plus_perm_def[where p="\<pi>\<^isub>1" and q="\<pi>\<^isub>2", THEN eq_reflection]} \hspace{4mm}
   262   @{thm plus_perm_def[where p="\<pi>\<^isub>1" and q="\<pi>\<^isub>2", THEN eq_reflection]} \hspace{5mm}
   214   @{thm uminus_perm_def[where p="\<pi>", THEN eq_reflection]} \hspace{4mm}
   263   @{thm uminus_perm_def[where p="\<pi>", THEN eq_reflection]} \hspace{5mm}
   215   @{thm minus_perm_def[where ?p1.0="\<pi>\<^isub>1" and ?p2.0="\<pi>\<^isub>2"]} 
   264   @{thm minus_perm_def[where ?p1.0="\<pi>\<^isub>1" and ?p2.0="\<pi>\<^isub>2"]} 
   216   \end{tabular}
   265   \end{tabular}
   217   \end{isabelle}
   266   \end{isabelle}
   218 
   267 
   219   \noindent
   268   \noindent
   220   and verify the simple properties
   269   and verify the simple properties
   221 
   270 
   222   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   271   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   223   \begin{tabular}{@ {}l}
   272   \begin{tabular}{@ {}l}
   224   @{thm add_assoc[where a="\<pi>\<^isub>1" and b="\<pi>\<^isub>2" and c="\<pi>\<^isub>3"]} \hspace{3mm}
   273   @{thm add_assoc[where a="\<pi>\<^isub>1" and b="\<pi>\<^isub>2" and c="\<pi>\<^isub>3"]} \hspace{5mm}
   225   @{thm monoid_add_class.add_0_left[where a="\<pi>::perm"]} \hspace{3mm}
   274   @{thm monoid_add_class.add_0_left[where a="\<pi>::perm"]} \hspace{5mm}
   226   @{thm monoid_add_class.add_0_right[where a="\<pi>::perm"]} \hspace{3mm}
   275   @{thm monoid_add_class.add_0_right[where a="\<pi>::perm"]} \hspace{5mm}
   227   @{thm group_add_class.left_minus[where a="\<pi>::perm"]} 
   276   @{thm group_add_class.left_minus[where a="\<pi>::perm"]} 
   228   \end{tabular}
   277   \end{tabular}
   229   \end{isabelle}
   278   \end{isabelle}
   230 
   279 
   231   \noindent
   280   \noindent
   232   Again this is in contrast to the list-of-pairs representation which does not
   281   The technical importance of this fact is that we can rely on
   233   form a group.  The technical importance of this fact is that we can rely on
       
   234   Isabelle/HOL's existing simplification infrastructure for groups, which will
   282   Isabelle/HOL's existing simplification infrastructure for groups, which will
   235   come in handy when we have to do calculations with permutations.
   283   come in handy when we have to do calculations with permutations.
   236   Note that Isabelle/HOL defies standard conventions of mathematical notation
   284   Note that Isabelle/HOL defies standard conventions of mathematical notation
   237   by using additive syntax even for non-commutative groups.  Obviously,
   285   by using additive syntax even for non-commutative groups.  Obviously,
   238   composition of permutations is not commutative in general, because @{text
   286   composition of permutations is not commutative in general, because @{text
   239   "\<pi>\<^sub>1 + \<pi>\<^sub>2 \<noteq>  \<pi>\<^sub>2 + \<pi>\<^sub>1"}.  But since the point of this paper is to implement the
   287   "\<pi>\<^sub>1 + \<pi>\<^sub>2 \<noteq>  \<pi>\<^sub>2 + \<pi>\<^sub>1"}.  But since the point of this paper is to implement the
   240   nominal theory as smoothly as possible in Isabelle/HOL, we tolerate
   288   nominal theory as smoothly as possible in Isabelle/HOL, we tolerate
   241   the non-standard notation in order to reuse the existing libraries.
   289   the non-standard notation in order to reuse the existing libraries.
   242 
   290 
   243   By formalising permutations abstractly as functions, and using a single type
   291   In order to reason abstractly about permutations, we state the following two 
   244   for all atoms, we can now restate the \emph{permutation properties} from
   292   \emph{permutation properties} 
   245   \eqref{permprops} as just the two equations
       
   246   
   293   
   247   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   294   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   248   \begin{tabular}{@ {}r@ {\hspace{4mm}}p{10cm}}
   295   \begin{tabular}{@ {}r@ {\hspace{4mm}}p{10cm}}
   249   i) & @{thm permute_zero[no_vars]}\\
   296   i) & @{thm permute_zero[no_vars]}\\
   250   ii) & @{thm permute_plus[where p="\<pi>\<^isub>1" and q="\<pi>\<^isub>2",no_vars]}
   297   ii) & @{thm permute_plus[where p="\<pi>\<^isub>1" and q="\<pi>\<^isub>2",no_vars]}
   251   \end{tabular}\hfill\numbered{newpermprops}
   298   \end{tabular}\hfill\numbered{newpermprops}
   252   \end{isabelle} 
   299   \end{isabelle} 
   253 
   300 
   254   \noindent
   301   \noindent
   255   in which the permutation operations are of type @{text "perm \<Rightarrow> \<beta> \<Rightarrow> \<beta>"} and so
   302   We state these properties in terms of Isabelle/HOL's type class 
   256   have only a single type parameter.  Consequently, these properties are
   303   mechanism \cite{}.
   257   compatible with the one-parameter restriction of Isabelle/HOL's type classes.
   304   This allows us to delegate much of the resoning involved in 
   258   There is no need to introduce a separate type class instantiated for each
   305   determining whether these properties are satisfied to the type system.
   259   sort, like in the old approach.
   306   For this we define
   260 
       
   261   The next notion allows us to establish generic lemmas involving the
       
   262   permutation operation.
       
   263 
   307 
   264   \begin{definition}
   308   \begin{definition}
   265   A type @{text "\<beta>"} is a \emph{permutation type} if the permutation
   309   A type @{text "\<beta>"} is a \emph{permutation type} if the permutation
   266   properties in \eqref{newpermprops} are satisfied for every @{text "x"} of type
   310   properties in \eqref{newpermprops} are satisfied for every @{text "x"} of type
   267   @{text "\<beta>"}.  
   311   @{text "\<beta>"}.  
   268   \end{definition}
   312   \end{definition}
   269 
   313 
   270   \noindent
   314   \noindent
   271   First, it follows from the laws governing
   315   The type class also allows us to establish generic lemmas involving the
       
   316   permutation operation. First, it follows from the laws governing
   272   groups that a permutation and its inverse cancel each other.  That is, for any
   317   groups that a permutation and its inverse cancel each other.  That is, for any
   273   @{text "x"} of a permutation type:
   318   @{text "x"} of a permutation type:
   274 
   319 
   275   
   320   
   276   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   321   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   279   @{thm permute_minus_cancel(2)[where p="\<pi>", no_vars]}
   324   @{thm permute_minus_cancel(2)[where p="\<pi>", no_vars]}
   280   \end{tabular}\hfill\numbered{cancel}
   325   \end{tabular}\hfill\numbered{cancel}
   281   \end{isabelle} 
   326   \end{isabelle} 
   282   
   327   
   283   \noindent
   328   \noindent
       
   329   ??? Proof
   284   Consequently, in a permutation type the permutation operation @{text "\<pi> \<bullet> _"}~~is bijective, 
   330   Consequently, in a permutation type the permutation operation @{text "\<pi> \<bullet> _"}~~is bijective, 
   285   which in turn implies the property
   331   which in turn implies the property
   286 
   332 
   287   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   333   \begin{isabelle}\ \ \ \ \ \ \ \ \ \ %%%
   288   \begin{tabular}{@ {}l}
   334   \begin{tabular}{@ {}l}
   314   \noindent
   360   \noindent
   315   In order to lift the permutation operation to other types, we can define for:
   361   In order to lift the permutation operation to other types, we can define for:
   316 
   362 
   317   \begin{equation}\label{permdefs}
   363   \begin{equation}\label{permdefs}
   318   \mbox{
   364   \mbox{
   319   \begin{tabular}{@ {}ll@ {\hspace{2mm}}l@ {}}
   365   \begin{tabular}{@ {}ll@ {\hspace{4mm}}l@ {}}
   320   1) & atoms: & @{thm permute_atom_def[where p="\<pi>",no_vars, THEN eq_reflection]}\\
   366   a) & atoms: & @{thm permute_atom_def[where p="\<pi>",no_vars, THEN eq_reflection]}\\
   321   2) & functions: &  @{text "\<pi> \<bullet> f \<equiv> \<lambda>x. \<pi> \<bullet> (f ((-\<pi>) \<bullet> x))"}\\
   367   b) & functions: &  @{text "\<pi> \<bullet> f \<equiv> \<lambda>x. \<pi> \<bullet> (f ((-\<pi>) \<bullet> x))"}\\
   322   3) & permutations: & @{thm permute_perm_def[where p="\<pi>" and q="\<pi>'", THEN eq_reflection]}\\
   368   c) & permutations: & @{thm permute_perm_def[where p="\<pi>" and q="\<pi>'", THEN eq_reflection]}\\
   323   4) & sets: & @{thm permute_set_eq[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   369   d) & sets: & @{thm permute_set_eq[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   324   5) & booleans: & @{thm permute_bool_def[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   370   e) & booleans: & @{thm permute_bool_def[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   325   6) & lists: & @{thm permute_list.simps(1)[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   371   f) & lists: & @{thm permute_list.simps(1)[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   326       & & @{thm permute_list.simps(2)[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   372       & & @{thm permute_list.simps(2)[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   327   7) & products: & @{thm permute_prod.simps[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   373   g) & products: & @{thm permute_prod.simps[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   328   8) & nats: & @{thm permute_nat_def[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   374   h) & nats: & @{thm permute_nat_def[where p="\<pi>", no_vars, THEN eq_reflection]}\\
   329   \end{tabular}}
   375   \end{tabular}}
   330   \end{equation}
   376   \end{equation}
   331 
   377 
   332   \noindent
   378   \noindent
   333   and then establish:
   379   and then establish: