src/HOL/Induct/Comb.thy
changeset 13075 d3e1d554cd6d
parent 11359 29f8b00d7e1f
child 15816 4575c87dd25b
equal deleted inserted replaced
13074:96bf406fd3e5 13075:d3e1d554cd6d
     1 (*  Title:      HOL/ex/Comb.thy
     1 (*  Title:      HOL/Induct/Comb.thy
     2     ID:         $Id$
     2     ID:         $Id$
     3     Author:     Lawrence C Paulson
     3     Author:     Lawrence C Paulson
     4     Copyright   1996  University of Cambridge
     4     Copyright   1996  University of Cambridge
     5 
       
     6 Combinatory Logic example: the Church-Rosser Theorem
       
     7 Curiously, combinators do not include free variables.
       
     8 
       
     9 Example taken from
       
    10     J. Camilleri and T. F. Melham.
       
    11     Reasoning with Inductively Defined Relations in the HOL Theorem Prover.
       
    12     Report 265, University of Cambridge Computer Laboratory, 1992.
       
    13 *)
     5 *)
    14 
     6 
    15 
     7 header {* Combinatory Logic example: the Church-Rosser Theorem *}
    16 Comb = Main +
     8 
    17 
     9 theory Comb = Main:
    18 (** Datatype definition of combinators S and K, with infixed application **)
    10 
       
    11 text {*
       
    12   Curiously, combinators do not include free variables.
       
    13 
       
    14   Example taken from \cite{camilleri-melham}.
       
    15 
       
    16 HOL system proofs may be found in the HOL distribution at
       
    17    .../contrib/rule-induction/cl.ml
       
    18 *}
       
    19 
       
    20 subsection {* Definitions *}
       
    21 
       
    22 text {* Datatype definition of combinators @{text S} and @{text K}. *}
       
    23 
    19 datatype comb = K
    24 datatype comb = K
    20               | S
    25               | S
    21               | "##" comb comb (infixl 90)
    26               | "##" comb comb (infixl 90)
    22 
    27 
    23 (** Inductive definition of contractions, -1->
    28 text {*
    24              and (multi-step) reductions, --->
    29   Inductive definition of contractions, @{text "-1->"} and
    25 **)
    30   (multi-step) reductions, @{text "--->"}.
       
    31 *}
       
    32 
    26 consts
    33 consts
    27   contract  :: "(comb*comb) set"
    34   contract  :: "(comb*comb) set"
    28   "-1->"    :: [comb,comb] => bool   (infixl 50)
    35   "-1->"    :: "[comb,comb] => bool"   (infixl 50)
    29   "--->"    :: [comb,comb] => bool   (infixl 50)
    36   "--->"    :: "[comb,comb] => bool"   (infixl 50)
    30 
    37 
    31 translations
    38 translations
    32   "x -1-> y" == "(x,y) : contract"
    39   "x -1-> y" == "(x,y) \<in> contract"
    33   "x ---> y" == "(x,y) : contract^*"
    40   "x ---> y" == "(x,y) \<in> contract^*"
    34 
    41 
    35 inductive contract
    42 inductive contract
    36   intrs
    43   intros
    37     K     "K##x##y -1-> x"
    44     K:     "K##x##y -1-> x"
    38     S     "S##x##y##z -1-> (x##z)##(y##z)"
    45     S:     "S##x##y##z -1-> (x##z)##(y##z)"
    39     Ap1   "x-1->y ==> x##z -1-> y##z"
    46     Ap1:   "x-1->y ==> x##z -1-> y##z"
    40     Ap2   "x-1->y ==> z##x -1-> z##y"
    47     Ap2:   "x-1->y ==> z##x -1-> z##y"
    41 
    48 
    42 
    49 text {*
    43 (** Inductive definition of parallel contractions, =1=>
    50   Inductive definition of parallel contractions, @{text "=1=>"} and
    44              and (multi-step) parallel reductions, ===>
    51   (multi-step) parallel reductions, @{text "===>"}.
    45 **)
    52 *}
       
    53 
    46 consts
    54 consts
    47   parcontract :: "(comb*comb) set"
    55   parcontract :: "(comb*comb) set"
    48   "=1=>"    :: [comb,comb] => bool   (infixl 50)
    56   "=1=>"      :: "[comb,comb] => bool"   (infixl 50)
    49   "===>"    :: [comb,comb] => bool   (infixl 50)
    57   "===>"      :: "[comb,comb] => bool"   (infixl 50)
    50 
    58 
    51 translations
    59 translations
    52   "x =1=> y" == "(x,y) : parcontract"
    60   "x =1=> y" == "(x,y) \<in> parcontract"
    53   "x ===> y" == "(x,y) : parcontract^*"
    61   "x ===> y" == "(x,y) \<in> parcontract^*"
    54 
    62 
    55 inductive parcontract
    63 inductive parcontract
    56   intrs
    64   intros
    57     refl  "x =1=> x"
    65     refl:  "x =1=> x"
    58     K     "K##x##y =1=> x"
    66     K:     "K##x##y =1=> x"
    59     S     "S##x##y##z =1=> (x##z)##(y##z)"
    67     S:     "S##x##y##z =1=> (x##z)##(y##z)"
    60     Ap    "[| x=1=>y;  z=1=>w |] ==> x##z =1=> y##w"
    68     Ap:    "[| x=1=>y;  z=1=>w |] ==> x##z =1=> y##w"
    61 
    69 
    62 
    70 text {*
    63 (*Misc definitions*)
    71   Misc definitions.
       
    72 *}
       
    73 
    64 constdefs
    74 constdefs
    65   I :: comb
    75   I :: comb
    66   "I == S##K##K"
    76   "I == S##K##K"
    67 
    77 
    68   (*confluence; Lambda/Commutation treats this more abstractly*)
       
    69   diamond   :: "('a * 'a)set => bool"	
    78   diamond   :: "('a * 'a)set => bool"	
    70   "diamond(r) == ALL x y. (x,y):r --> 
    79     --{*confluence; Lambda/Commutation treats this more abstractly*}
    71                   (ALL y'. (x,y'):r --> 
    80   "diamond(r) == \<forall>x y. (x,y) \<in> r --> 
    72                     (EX z. (y,z):r & (y',z) : r))"
    81                   (\<forall>y'. (x,y') \<in> r --> 
       
    82                     (\<exists>z. (y,z) \<in> r & (y',z) \<in> r))"
       
    83 
       
    84 
       
    85 subsection {*Reflexive/Transitive closure preserves Church-Rosser property*}
       
    86 
       
    87 text{*So does the Transitive closure, with a similar proof*}
       
    88 
       
    89 text{*Strip lemma.  
       
    90    The induction hypothesis covers all but the last diamond of the strip.*}
       
    91 lemma diamond_strip_lemmaE [rule_format]: 
       
    92     "[| diamond(r);  (x,y) \<in> r^* |] ==>   
       
    93           \<forall>y'. (x,y') \<in> r --> (\<exists>z. (y',z) \<in> r^* & (y,z) \<in> r)"
       
    94 apply (unfold diamond_def)
       
    95 apply (erule rtrancl_induct, blast, clarify)
       
    96 apply (drule spec, drule mp, assumption)
       
    97 apply (blast intro: rtrancl_trans [OF _ r_into_rtrancl])
       
    98 done
       
    99 
       
   100 lemma diamond_rtrancl: "diamond(r) ==> diamond(r^*)"
       
   101 apply (simp (no_asm_simp) add: diamond_def)
       
   102 apply (rule impI [THEN allI, THEN allI])
       
   103 apply (erule rtrancl_induct, blast)
       
   104 apply (best intro: rtrancl_trans [OF _ r_into_rtrancl] 
       
   105             elim: diamond_strip_lemmaE [THEN exE])
       
   106 done
       
   107 
       
   108 
       
   109 subsection {* Non-contraction results *}
       
   110 
       
   111 text {* Derive a case for each combinator constructor. *}
       
   112 
       
   113 inductive_cases
       
   114       K_contractE [elim!]: "K -1-> r"
       
   115   and S_contractE [elim!]: "S -1-> r"
       
   116   and Ap_contractE [elim!]: "p##q -1-> r"
       
   117 
       
   118 declare contract.K [intro!] contract.S [intro!]
       
   119 declare contract.Ap1 [intro] contract.Ap2 [intro]
       
   120 
       
   121 lemma I_contract_E [elim!]: "I -1-> z ==> P"
       
   122 by (unfold I_def, blast)
       
   123 
       
   124 lemma K1_contractD [elim!]: "K##x -1-> z ==> (\<exists>x'. z = K##x' & x -1-> x')"
       
   125 by blast
       
   126 
       
   127 lemma Ap_reduce1 [intro]: "x ---> y ==> x##z ---> y##z"
       
   128 apply (erule rtrancl_induct)
       
   129 apply (blast intro: rtrancl_trans)+
       
   130 done
       
   131 
       
   132 lemma Ap_reduce2 [intro]: "x ---> y ==> z##x ---> z##y"
       
   133 apply (erule rtrancl_induct)
       
   134 apply (blast intro: rtrancl_trans)+
       
   135 done
       
   136 
       
   137 (** Counterexample to the diamond property for -1-> **)
       
   138 
       
   139 lemma KIII_contract1: "K##I##(I##I) -1-> I"
       
   140 by (rule contract.K)
       
   141 
       
   142 lemma KIII_contract2: "K##I##(I##I) -1-> K##I##((K##I)##(K##I))"
       
   143 by (unfold I_def, blast)
       
   144 
       
   145 lemma KIII_contract3: "K##I##((K##I)##(K##I)) -1-> I"
       
   146 by blast
       
   147 
       
   148 lemma not_diamond_contract: "~ diamond(contract)"
       
   149 apply (unfold diamond_def) 
       
   150 apply (best intro: KIII_contract1 KIII_contract2 KIII_contract3)
       
   151 done
       
   152 
       
   153 
       
   154 subsection {* Results about Parallel Contraction *}
       
   155 
       
   156 text {* Derive a case for each combinator constructor. *}
       
   157 
       
   158 inductive_cases
       
   159       K_parcontractE [elim!]: "K =1=> r"
       
   160   and S_parcontractE [elim!]: "S =1=> r"
       
   161   and Ap_parcontractE [elim!]: "p##q =1=> r"
       
   162 
       
   163 declare parcontract.intros [intro]
       
   164 
       
   165 (*** Basic properties of parallel contraction ***)
       
   166 
       
   167 subsection {* Basic properties of parallel contraction *}
       
   168 
       
   169 lemma K1_parcontractD [dest!]: "K##x =1=> z ==> (\<exists>x'. z = K##x' & x =1=> x')"
       
   170 by blast
       
   171 
       
   172 lemma S1_parcontractD [dest!]: "S##x =1=> z ==> (\<exists>x'. z = S##x' & x =1=> x')"
       
   173 by blast
       
   174 
       
   175 lemma S2_parcontractD [dest!]:
       
   176      "S##x##y =1=> z ==> (\<exists>x' y'. z = S##x'##y' & x =1=> x' & y =1=> y')"
       
   177 by blast
       
   178 
       
   179 text{*The rules above are not essential but make proofs much faster*}
       
   180 
       
   181 text{*Church-Rosser property for parallel contraction*}
       
   182 lemma diamond_parcontract: "diamond parcontract"
       
   183 apply (unfold diamond_def)
       
   184 apply (rule impI [THEN allI, THEN allI])
       
   185 apply (erule parcontract.induct, fast+)
       
   186 done
       
   187 
       
   188 text {*
       
   189   \medskip Equivalence of @{prop "p ---> q"} and @{prop "p ===> q"}.
       
   190 *}
       
   191 
       
   192 lemma contract_subset_parcontract: "contract <= parcontract"
       
   193 apply (rule subsetI)
       
   194 apply (simp only: split_tupled_all)
       
   195 apply (erule contract.induct, blast+)
       
   196 done
       
   197 
       
   198 text{*Reductions: simply throw together reflexivity, transitivity and
       
   199   the one-step reductions*}
       
   200 
       
   201 declare r_into_rtrancl [intro]  rtrancl_trans [intro]
       
   202 
       
   203 (*Example only: not used*)
       
   204 lemma reduce_I: "I##x ---> x"
       
   205 by (unfold I_def, blast)
       
   206 
       
   207 lemma parcontract_subset_reduce: "parcontract <= contract^*"
       
   208 apply (rule subsetI)
       
   209 apply (simp only: split_tupled_all)
       
   210 apply (erule parcontract.induct , blast+)
       
   211 done
       
   212 
       
   213 lemma reduce_eq_parreduce: "contract^* = parcontract^*"
       
   214 by (rule equalityI contract_subset_parcontract [THEN rtrancl_mono] 
       
   215          parcontract_subset_reduce [THEN rtrancl_subset_rtrancl])+
       
   216 
       
   217 lemma diamond_reduce: "diamond(contract^*)"
       
   218 by (simp add: reduce_eq_parreduce diamond_rtrancl diamond_parcontract)
    73 
   219 
    74 end
   220 end