src/HOL/Lambda/Lambda.ML
changeset 1266 3ae9fe3c0f68
parent 1172 ab725b698cb2
child 1269 ee011b365770
equal deleted inserted replaced
1265:6ef9a9893fd6 1266:3ae9fe3c0f68
    13 (*** Nat ***)
    13 (*** Nat ***)
    14 
    14 
    15 goal Nat.thy "!!i. [| i < Suc j; j < k |] ==> i < k";
    15 goal Nat.thy "!!i. [| i < Suc j; j < k |] ==> i < k";
    16 br le_less_trans 1;
    16 br le_less_trans 1;
    17 ba 2;
    17 ba 2;
    18 by(asm_full_simp_tac (nat_ss addsimps [le_def]) 1);
    18 by(asm_full_simp_tac (!simpset addsimps [le_def]) 1);
    19 by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1);
    19 by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1);
    20 qed "lt_trans1";
    20 qed "lt_trans1";
    21 
    21 
    22 goal Nat.thy "!!i. [| i < j; j < Suc(k) |] ==> i < k";
    22 goal Nat.thy "!!i. [| i < j; j < Suc(k) |] ==> i < k";
    23 be less_le_trans 1;
    23 be less_le_trans 1;
    24 by(asm_full_simp_tac (nat_ss addsimps [le_def]) 1);
    24 by(asm_full_simp_tac (!simpset addsimps [le_def]) 1);
    25 by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1);
    25 by(fast_tac (HOL_cs addEs [less_asym,less_anti_refl]) 1);
    26 qed "lt_trans2";
    26 qed "lt_trans2";
    27 
    27 
    28 val major::prems = goal Nat.thy
    28 val major::prems = goal Nat.thy
    29   "[| i < Suc j; i < j ==> P; i = j ==> P |] ==> P";
    29   "[| i < Suc j; i < j ==> P; i = j ==> P |] ==> P";
    30 br (major RS lessE) 1;
    30 br (major RS lessE) 1;
    31 by(ALLGOALS(asm_full_simp_tac nat_ss));
    31 by(ALLGOALS Asm_full_simp_tac);
    32 by(resolve_tac prems 1 THEN etac sym 1);
    32 by(resolve_tac prems 1 THEN etac sym 1);
    33 by(fast_tac (HOL_cs addIs prems) 1);
    33 by(fast_tac (HOL_cs addIs prems) 1);
    34 qed "leqE";
    34 qed "leqE";
    35 
    35 
    36 goal Arith.thy "!!i. i < j ==> Suc(pred j) = j";
    36 goal Arith.thy "!!i. i < j ==> Suc(pred j) = j";
    37 by(fast_tac (HOL_cs addEs [lessE] addss arith_ss) 1);
    37 by(fast_tac (HOL_cs addEs [lessE] addss !simpset) 1);
    38 qed "Suc_pred";
    38 qed "Suc_pred";
    39 
    39 
    40 goal Arith.thy "!!i. Suc i < j ==> i < pred j ";
    40 goal Arith.thy "!!i. Suc i < j ==> i < pred j ";
    41 by (resolve_tac [Suc_less_SucD] 1);
    41 by (resolve_tac [Suc_less_SucD] 1);
    42 by (asm_simp_tac (arith_ss addsimps [Suc_pred]) 1);
    42 by (asm_simp_tac (!simpset addsimps [Suc_pred]) 1);
    43 qed "lt_pred";
    43 qed "lt_pred";
    44 
    44 
    45 goal Arith.thy "!!i. [| i < Suc j; k < i |] ==> pred i < j ";
    45 goal Arith.thy "!!i. [| i < Suc j; k < i |] ==> pred i < j ";
    46 by (resolve_tac [Suc_less_SucD] 1);
    46 by (resolve_tac [Suc_less_SucD] 1);
    47 by (asm_simp_tac (arith_ss addsimps [Suc_pred]) 1);
    47 by (asm_simp_tac (!simpset addsimps [Suc_pred]) 1);
    48 qed "gt_pred";
    48 qed "gt_pred";
    49 
    49 
    50 
    50 
    51 (*** Lambda ***)
    51 (*** Lambda ***)
    52 
    52 
    53 open Lambda;
    53 open Lambda;
    54 
    54 
    55 val lambda_ss = arith_ss delsimps [less_Suc_eq] addsimps
    55 Addsimps [if_not_P, not_less_eq];
    56   db.simps @ beta.intrs @
       
    57   [if_not_P, not_less_eq,
       
    58    subst_App,subst_Fun,
       
    59    lift_Var,lift_App,lift_Fun];
       
    60 
    56 
    61 val lambda_cs = HOL_cs addSIs beta.intrs;
    57 val lambda_cs = HOL_cs addSIs beta.intrs;
    62 
    58 
    63 (*** Congruence rules for ->> ***)
    59 (*** Congruence rules for ->> ***)
    64 
    60 
    82                 [rtrancl_beta_AppL,rtrancl_beta_AppR,rtrancl_trans]) 1);
    78                 [rtrancl_beta_AppL,rtrancl_beta_AppR,rtrancl_trans]) 1);
    83 qed "rtrancl_beta_App";
    79 qed "rtrancl_beta_App";
    84 
    80 
    85 (*** subst and lift ***)
    81 (*** subst and lift ***)
    86 
    82 
    87 fun addsplit ss = ss addsimps [subst_Var] setloop (split_tac [expand_if]);
    83 val split_ss = !simpset delsimps [less_Suc_eq,subst_Var]
       
    84                         addsimps [subst_Var]
       
    85                         setloop (split_tac [expand_if]);
    88 
    86 
    89 goal Lambda.thy "(Var k)[u/k] = u";
    87 goal Lambda.thy "(Var k)[u/k] = u";
    90 by (asm_full_simp_tac (addsplit lambda_ss) 1);
    88 by (asm_full_simp_tac split_ss 1);
    91 qed "subst_eq";
    89 qed "subst_eq";
    92 
    90 
    93 goal Lambda.thy "!!s. i<j ==> (Var j)[u/i] = Var(pred j)";
    91 goal Lambda.thy "!!s. i<j ==> (Var j)[u/i] = Var(pred j)";
    94 by (asm_full_simp_tac (addsplit lambda_ss) 1);
    92 by (asm_full_simp_tac split_ss 1);
    95 qed "subst_gt";
    93 qed "subst_gt";
    96 
    94 
    97 goal Lambda.thy "!!s. j<i ==> (Var j)[u/i] = Var(j)";
    95 goal Lambda.thy "!!s. j<i ==> (Var j)[u/i] = Var(j)";
    98 by (asm_full_simp_tac (addsplit lambda_ss addsimps
    96 by (asm_full_simp_tac (split_ss addsimps
    99                           [less_not_refl2 RS not_sym,less_SucI]) 1);
    97                           [less_not_refl2 RS not_sym,less_SucI]) 1);
   100 qed "subst_lt";
    98 qed "subst_lt";
   101 
    99 
   102 val lambda_ss = lambda_ss addsimps [subst_eq,subst_gt,subst_lt];
   100 Addsimps [subst_eq,subst_gt,subst_lt];
       
   101 val ss = !simpset delsimps [less_Suc_eq, subst_Var];
   103 
   102 
   104 goal Lambda.thy
   103 goal Lambda.thy
   105   "!i k. i < Suc k --> lift (lift t i) (Suc k) = lift (lift t k) i";
   104   "!i k. i < Suc k --> lift (lift t i) (Suc k) = lift (lift t k) i";
   106 by(db.induct_tac "t" 1);
   105 by(db.induct_tac "t" 1);
   107 by(ALLGOALS(asm_simp_tac lambda_ss));
   106 by(ALLGOALS (asm_simp_tac ss));
   108 by(strip_tac 1);
   107 by(strip_tac 1);
   109 by (excluded_middle_tac "nat < i" 1);
   108 by (excluded_middle_tac "nat < i" 1);
   110 by ((forward_tac [lt_trans2] 2) THEN (assume_tac 2));
   109 by ((forward_tac [lt_trans2] 2) THEN (assume_tac 2));
   111 by (ALLGOALS(asm_full_simp_tac ((addsplit lambda_ss) addsimps [less_SucI])));
   110 by (ALLGOALS(asm_full_simp_tac (split_ss addsimps [less_SucI])));
   112 qed"lift_lift";
   111 qed"lift_lift";
   113 
   112 
   114 goal Lambda.thy "!i j s. j < Suc i --> \
   113 goal Lambda.thy "!i j s. j < Suc i --> \
   115 \         lift (t[s/j]) i = (lift t (Suc i)) [lift s i / j]";
   114 \         lift (t[s/j]) i = (lift t (Suc i)) [lift s i / j]";
   116 by(db.induct_tac "t" 1);
   115 by(db.induct_tac "t" 1);
   117 by(ALLGOALS(asm_simp_tac (lambda_ss addsimps [lift_lift])));
   116 by(ALLGOALS(asm_simp_tac (ss addsimps [lift_lift])));
   118 by(strip_tac 1);
   117 by(strip_tac 1);
   119 by (excluded_middle_tac "nat < j" 1);
   118 by (excluded_middle_tac "nat < j" 1);
   120 by (asm_full_simp_tac lambda_ss 1);
   119 by (asm_full_simp_tac ss 1);
   121 by (eres_inst_tac [("j","nat")] leqE 1);
   120 by (eres_inst_tac [("j","nat")] leqE 1);
   122 by (asm_full_simp_tac ((addsplit lambda_ss) 
   121 by (asm_full_simp_tac (split_ss addsimps [less_SucI,gt_pred,Suc_pred]) 1);
   123                         addsimps [less_SucI,gt_pred,Suc_pred]) 1);
       
   124 by (hyp_subst_tac 1);
   122 by (hyp_subst_tac 1);
   125 by (asm_simp_tac lambda_ss 1);
   123 by (Asm_simp_tac 1);
   126 by (forw_inst_tac [("j","j")] lt_trans2 1);
   124 by (forw_inst_tac [("j","j")] lt_trans2 1);
   127 by (assume_tac 1);
   125 by (assume_tac 1);
   128 by (asm_full_simp_tac (addsplit lambda_ss addsimps [less_SucI]) 1);
   126 by (asm_full_simp_tac (split_ss addsimps [less_SucI]) 1);
   129 qed "lift_subst";
   127 qed "lift_subst";
   130 val lambda_ss = lambda_ss addsimps [lift_subst];
   128 Addsimps [lift_subst];
   131 
   129 
   132 goal Lambda.thy
   130 goal Lambda.thy
   133   "!i j s. i < Suc j -->\
   131   "!i j s. i < Suc j -->\
   134 \         lift (t[s/j]) i = (lift t i) [lift s i / Suc j]";
   132 \         lift (t[s/j]) i = (lift t i) [lift s i / Suc j]";
   135 by(db.induct_tac "t" 1);
   133 by(db.induct_tac "t" 1);
   136 by(ALLGOALS(asm_simp_tac (lambda_ss addsimps [lift_lift])));
   134 by(ALLGOALS(asm_simp_tac (ss addsimps [lift_lift])));
   137 by(strip_tac 1);
   135 by(strip_tac 1);
   138 by (excluded_middle_tac "nat < j" 1);
   136 by (excluded_middle_tac "nat < j" 1);
   139 by (asm_full_simp_tac lambda_ss 1);
   137 by (asm_full_simp_tac ss 1);
   140 by (eres_inst_tac [("i","j")] leqE 1);
   138 by (eres_inst_tac [("i","j")] leqE 1);
   141 by (forward_tac  [lt_trans1] 1 THEN assume_tac 1);
   139 by (forward_tac  [lt_trans1] 1 THEN assume_tac 1);
   142 by (ALLGOALS(asm_full_simp_tac 
   140 by (ALLGOALS(asm_full_simp_tac (ss addsimps [Suc_pred,less_SucI,gt_pred])));
   143 	     (lambda_ss addsimps [Suc_pred,less_SucI,gt_pred])));
       
   144 by (hyp_subst_tac 1);
   141 by (hyp_subst_tac 1);
   145 by (asm_full_simp_tac (lambda_ss addsimps [less_SucI]) 1);
   142 by (asm_full_simp_tac (ss addsimps [less_SucI]) 1);
   146 by(split_tac [expand_if] 1);
   143 by(split_tac [expand_if] 1);
   147 by (asm_full_simp_tac (lambda_ss addsimps [less_SucI]) 1);
   144 by (asm_full_simp_tac (!simpset addsimps [less_SucI]) 1);
   148 qed "lift_subst_lt";
   145 qed "lift_subst_lt";
   149 
   146 
   150 goal Lambda.thy "!k s. (lift t k)[s/k] = t";
   147 goal Lambda.thy "!k s. (lift t k)[s/k] = t";
   151 by(db.induct_tac "t" 1);
   148 by(db.induct_tac "t" 1);
   152 by(ALLGOALS(asm_simp_tac lambda_ss));
   149 by(ALLGOALS Asm_simp_tac);
   153 by(split_tac [expand_if] 1);
   150 by(split_tac [expand_if] 1);
   154 by(ALLGOALS(asm_full_simp_tac lambda_ss));
   151 by(ALLGOALS Asm_full_simp_tac);
   155 qed "subst_lift";
   152 qed "subst_lift";
   156 val lambda_ss = lambda_ss addsimps [subst_lift];
   153 Addsimps [subst_lift];
   157 
   154 
   158 
   155 
   159 goal Lambda.thy "!i j u v. i < Suc j --> \
   156 goal Lambda.thy "!i j u v. i < Suc j --> \
   160 \ t[lift v i / Suc j][u[v/j]/i] = t[u/i][v/j]";
   157 \ t[lift v i / Suc j][u[v/j]/i] = t[u/i][v/j]";
   161 by(db.induct_tac "t" 1);
   158 by(db.induct_tac "t" 1);
   162 by (ALLGOALS(asm_simp_tac (lambda_ss addsimps
   159 by (ALLGOALS(asm_simp_tac (ss addsimps
   163                    [lift_lift RS spec RS spec RS mp RS sym,lift_subst_lt])));
   160                    [lift_lift RS spec RS spec RS mp RS sym,lift_subst_lt])));
   164 by(strip_tac 1);
   161 by(strip_tac 1);
   165 by (excluded_middle_tac "nat < Suc(Suc j)" 1);
   162 by (excluded_middle_tac "nat < Suc(Suc j)" 1);
   166 by(asm_full_simp_tac lambda_ss 1);
   163 by(asm_full_simp_tac ss 1);
   167 by (forward_tac [lessI RS less_trans] 1);
   164 by (forward_tac [lessI RS less_trans] 1);
   168 by (eresolve_tac [leqE] 1);
   165 by (eresolve_tac [leqE] 1);
   169 by (asm_simp_tac (lambda_ss addsimps [Suc_pred,lt_pred]) 2);
   166 by (asm_simp_tac (ss addsimps [Suc_pred,lt_pred]) 2);
   170 by (forward_tac [Suc_mono RS less_trans] 1 THEN assume_tac 1);
   167 by (forward_tac [Suc_mono RS less_trans] 1 THEN assume_tac 1);
   171 by (forw_inst_tac [("i","i")] (lessI RS less_trans) 1);
   168 by (forw_inst_tac [("i","i")] (lessI RS less_trans) 1);
   172 by (asm_simp_tac (lambda_ss addsimps [Suc_pred,lt_pred]) 1);
   169 by (asm_simp_tac (ss addsimps [Suc_pred,lt_pred]) 1);
   173 by (eres_inst_tac [("i","nat")] leqE 1);
   170 by (eres_inst_tac [("i","nat")] leqE 1);
   174 by (asm_full_simp_tac (lambda_ss addsimps [Suc_pred,less_SucI]) 2);
   171 by (asm_full_simp_tac (!simpset delsimps [less_Suc_eq]
       
   172                                 addsimps [Suc_pred,less_SucI]) 2);
   175 by (excluded_middle_tac "nat < i" 1);
   173 by (excluded_middle_tac "nat < i" 1);
   176 by (asm_full_simp_tac lambda_ss 1);
   174 by (asm_full_simp_tac ss 1);
   177 by (eres_inst_tac [("j","nat")] leqE 1);
   175 by (eres_inst_tac [("j","nat")] leqE 1);
   178 by (asm_simp_tac (lambda_ss addsimps [gt_pred]) 1);
   176 by (asm_simp_tac (!simpset addsimps [gt_pred]) 1);
   179 by (asm_simp_tac lambda_ss 1);
   177 by (Asm_simp_tac 1);
   180 by (forward_tac [lt_trans2] 1 THEN assume_tac 1);
   178 by (forward_tac [lt_trans2] 1 THEN assume_tac 1);
   181 by (asm_simp_tac (lambda_ss addsimps [gt_pred]) 1);
   179 by (asm_simp_tac (!simpset addsimps [gt_pred]) 1);
   182 bind_thm("subst_subst", result() RS spec RS spec RS spec RS spec RS mp);
   180 bind_thm("subst_subst", result() RS spec RS spec RS spec RS spec RS mp);
   183 
   181 
   184 val lambda_ss = lambda_ss addsimps
       
   185   [liftn_Var,liftn_App,liftn_Fun,substn_Var,substn_App,substn_Fun];
       
   186 
   182 
   187 (*** Equivalence proof for optimized substitution ***)
   183 (*** Equivalence proof for optimized substitution ***)
   188 
   184 
   189 goal Lambda.thy "!k. liftn 0 t k = t";
   185 goal Lambda.thy "!k. liftn 0 t k = t";
   190 by(db.induct_tac "t" 1);
   186 by(db.induct_tac "t" 1);
   191 by(ALLGOALS(asm_simp_tac (addsplit lambda_ss)));
   187 by(ALLGOALS(asm_simp_tac split_ss));
   192 qed "liftn_0";
   188 qed "liftn_0";
   193 val lambda_ss = lambda_ss addsimps [liftn_0];
   189 Addsimps [liftn_0];
   194 
   190 
   195 goal Lambda.thy "!k. liftn (Suc n) t k = lift (liftn n t k) k";
   191 goal Lambda.thy "!k. liftn (Suc n) t k = lift (liftn n t k) k";
   196 by(db.induct_tac "t" 1);
   192 by(db.induct_tac "t" 1);
   197 by(ALLGOALS(asm_simp_tac (addsplit lambda_ss)));
   193 by(ALLGOALS(asm_simp_tac split_ss));
   198 by(fast_tac (HOL_cs addDs [add_lessD1]) 1);
   194 by(fast_tac (HOL_cs addDs [add_lessD1]) 1);
   199 qed "liftn_lift";
   195 qed "liftn_lift";
   200 val lambda_ss = lambda_ss addsimps [liftn_lift];
   196 Addsimps [liftn_lift];
   201 
   197 
   202 goal Lambda.thy "!n. substn t s n = t[liftn n s 0 / n]";
   198 goal Lambda.thy "!n. substn t s n = t[liftn n s 0 / n]";
   203 by(db.induct_tac "t" 1);
   199 by(db.induct_tac "t" 1);
   204 by(ALLGOALS(asm_simp_tac (addsplit lambda_ss)));
   200 by(ALLGOALS(asm_simp_tac (!simpset setloop (split_tac [expand_if]))));
   205 qed "substn_subst_n";
   201 qed "substn_subst_n";
   206 val lambda_ss = lambda_ss addsimps [substn_subst_n];
   202 Addsimps [substn_subst_n];
   207 
   203 
   208 goal Lambda.thy "substn t s 0 = t[s/0]";
   204 goal Lambda.thy "substn t s 0 = t[s/0]";
   209 by(simp_tac lambda_ss 1);
   205 by(Simp_tac 1);
   210 qed "substn_subst_0";
   206 qed "substn_subst_0";