src/Pure/raw_simplifier.ML
changeset 54725 fc384e0a7f51
parent 54724 b92694e756b8
child 54727 a806e7251cf0
equal deleted inserted replaced
54724:b92694e756b8 54725:fc384e0a7f51
   944           if fo then Thm.first_order_match (elhs', eta_t')
   944           if fo then Thm.first_order_match (elhs', eta_t')
   945           else Thm.match (elhs', eta_t');
   945           else Thm.match (elhs', eta_t');
   946         val thm' = Thm.instantiate insts (Thm.rename_boundvars lhs eta_t rthm);
   946         val thm' = Thm.instantiate insts (Thm.rename_boundvars lhs eta_t rthm);
   947         val prop' = Thm.prop_of thm';
   947         val prop' = Thm.prop_of thm';
   948         val unconditional = (Logic.count_prems prop' = 0);
   948         val unconditional = (Logic.count_prems prop' = 0);
   949         val (lhs', rhs') = Logic.dest_equals (Logic.strip_imp_concl prop')
   949         val (lhs', rhs') = Logic.dest_equals (Logic.strip_imp_concl prop');
   950       in
   950       in
   951         if perm andalso not (termless (rhs', lhs'))
   951         if perm andalso not (termless (rhs', lhs'))
   952         then (trace_named_thm ctxt (fn () => "Cannot apply permutative rewrite rule") (thm, name);
   952         then
   953               trace_thm ctxt (fn () => "Term does not become smaller:") thm'; NONE)
   953          (trace_named_thm ctxt (fn () => "Cannot apply permutative rewrite rule") (thm, name);
   954         else (trace_named_thm ctxt (fn () => "Applying instance of rewrite rule") (thm, name);
   954           trace_thm ctxt (fn () => "Term does not become smaller:") thm';
   955            if unconditional
   955           NONE)
   956            then
   956         else
   957              (trace_thm ctxt (fn () => "Rewriting:") thm';
   957          (trace_named_thm ctxt (fn () => "Applying instance of rewrite rule") (thm, name);
       
   958           if unconditional
       
   959           then
       
   960            (trace_thm ctxt (fn () => "Rewriting:") thm';
       
   961             let
       
   962               val lr = Logic.dest_equals prop;
       
   963               val SOME thm'' = check_conv ctxt false eta_thm thm';
       
   964             in SOME (thm'', uncond_skel (congs, lr)) end)
       
   965           else
       
   966            (trace_thm ctxt (fn () => "Trying to rewrite:") thm';
       
   967             if simp_depth ctxt > Config.get ctxt simp_depth_limit
       
   968             then
   958               let
   969               let
   959                 val lr = Logic.dest_equals prop;
   970                 val s = "simp_depth_limit exceeded - giving up";
   960                 val SOME thm'' = check_conv ctxt false eta_thm thm';
   971                 val _ = trace ctxt false (fn () => s);
   961               in SOME (thm'', uncond_skel (congs, lr)) end)
   972                 val _ = Context_Position.if_visible ctxt warning s;
   962            else
   973               in NONE end
   963              (trace_thm ctxt (fn () => "Trying to rewrite:") thm';
   974             else
   964               if simp_depth ctxt > Config.get ctxt simp_depth_limit
   975               (case prover ctxt thm' of
   965               then
       
   966                 let
       
   967                   val s = "simp_depth_limit exceeded - giving up";
       
   968                   val _ = trace ctxt false (fn () => s);
       
   969                   val _ = Context_Position.if_visible ctxt warning s;
       
   970                 in NONE end
       
   971               else
       
   972               case prover ctxt thm' of
       
   973                 NONE => (trace_thm ctxt (fn () => "FAILED") thm'; NONE)
   976                 NONE => (trace_thm ctxt (fn () => "FAILED") thm'; NONE)
   974               | SOME thm2 =>
   977               | SOME thm2 =>
   975                   (case check_conv ctxt true eta_thm thm2 of
   978                   (case check_conv ctxt true eta_thm thm2 of
   976                     NONE => NONE
   979                     NONE => NONE
   977                   | SOME thm2' =>
   980                   | SOME thm2' =>
   978                       let
   981                       let
   979                         val concl = Logic.strip_imp_concl prop;
   982                         val concl = Logic.strip_imp_concl prop;
   980                         val lr = Logic.dest_equals concl;
   983                         val lr = Logic.dest_equals concl;
   981                       in SOME (thm2', cond_skel (congs, lr)) end)))
   984                       in SOME (thm2', cond_skel (congs, lr)) end))))
   982       end;
   985       end;
   983 
   986 
   984     fun rews [] = NONE
   987     fun rews [] = NONE
   985       | rews (rrule :: rrules) =
   988       | rews (rrule :: rrules) =
   986           let val opt = rew rrule handle Pattern.MATCH => NONE
   989           let val opt = rew rrule handle Pattern.MATCH => NONE
   987           in case opt of NONE => rews rrules | some => some end;
   990           in (case opt of NONE => rews rrules | some => some) end;
   988 
   991 
   989     fun sort_rrules rrs =
   992     fun sort_rrules rrs =
   990       let
   993       let
   991         fun is_simple ({thm, ...}: rrule) =
   994         fun is_simple ({thm, ...}: rrule) =
   992           (case Thm.prop_of thm of
   995           (case Thm.prop_of thm of
  1001 
  1004 
  1002     fun proc_rews [] = NONE
  1005     fun proc_rews [] = NONE
  1003       | proc_rews (Proc {name, proc, lhs, ...} :: ps) =
  1006       | proc_rews (Proc {name, proc, lhs, ...} :: ps) =
  1004           if Pattern.matches (Proof_Context.theory_of ctxt) (Thm.term_of lhs, Thm.term_of t) then
  1007           if Pattern.matches (Proof_Context.theory_of ctxt) (Thm.term_of lhs, Thm.term_of t) then
  1005             (debug_term ctxt false (fn () => "Trying procedure " ^ quote name ^ " on:") eta_t;
  1008             (debug_term ctxt false (fn () => "Trying procedure " ^ quote name ^ " on:") eta_t;
  1006              case proc ctxt eta_t' of
  1009              (case proc ctxt eta_t' of
  1007                NONE => (debug ctxt false (fn () => "FAILED"); proc_rews ps)
  1010                NONE => (debug ctxt false (fn () => "FAILED"); proc_rews ps)
  1008              | SOME raw_thm =>
  1011              | SOME raw_thm =>
  1009                  (trace_thm ctxt (fn () => "Procedure " ^ quote name ^ " produced rewrite rule:")
  1012                  (trace_thm ctxt (fn () => "Procedure " ^ quote name ^ " produced rewrite rule:")
  1010                    raw_thm;
  1013                    raw_thm;
  1011                   (case rews (mk_procrule ctxt raw_thm) of
  1014                   (case rews (mk_procrule ctxt raw_thm) of
  1012                     NONE => (trace_cterm ctxt true (fn () => "IGNORED result of simproc " ^ quote name ^
  1015                     NONE => (trace_cterm ctxt true (fn () => "IGNORED result of simproc " ^ quote name ^
  1013                       " -- does not match") t; proc_rews ps)
  1016                       " -- does not match") t; proc_rews ps)
  1014                   | some => some)))
  1017                   | some => some))))
  1015           else proc_rews ps;
  1018           else proc_rews ps;
  1016   in
  1019   in
  1017     (case eta_t of
  1020     (case eta_t of
  1018       Abs _ $ _ => SOME (Thm.transitive eta_thm (Thm.beta_conversion false eta_t'), skel0)
  1021       Abs _ $ _ => SOME (Thm.transitive eta_thm (Thm.beta_conversion false eta_t'), skel0)
  1019     | _ =>
  1022     | _ =>
  1050   apsnd Thm.dest_equals (Thm.dest_implies (hd (cprems_of Drule.imp_cong)));
  1053   apsnd Thm.dest_equals (Thm.dest_implies (hd (cprems_of Drule.imp_cong)));
  1051 
  1054 
  1052 fun transitive1 NONE NONE = NONE
  1055 fun transitive1 NONE NONE = NONE
  1053   | transitive1 (SOME thm1) NONE = SOME thm1
  1056   | transitive1 (SOME thm1) NONE = SOME thm1
  1054   | transitive1 NONE (SOME thm2) = SOME thm2
  1057   | transitive1 NONE (SOME thm2) = SOME thm2
  1055   | transitive1 (SOME thm1) (SOME thm2) = SOME (Thm.transitive thm1 thm2)
  1058   | transitive1 (SOME thm1) (SOME thm2) = SOME (Thm.transitive thm1 thm2);
  1056 
  1059 
  1057 fun transitive2 thm = transitive1 (SOME thm);
  1060 fun transitive2 thm = transitive1 (SOME thm);
  1058 fun transitive3 thm = transitive1 thm o SOME;
  1061 fun transitive3 thm = transitive1 thm o SOME;
  1059 
  1062 
  1060 fun bottomc ((simprem, useprem, mutsimp), prover, maxidx) =
  1063 fun bottomc ((simprem, useprem, mutsimp), prover, maxidx) =
  1061   let
  1064   let
  1062     fun botc skel ctxt t =
  1065     fun botc skel ctxt t =
  1063           if is_Var skel then NONE
  1066       if is_Var skel then NONE
  1064           else
  1067       else
  1065           (case subc skel ctxt t of
  1068         (case subc skel ctxt t of
  1066              some as SOME thm1 =>
  1069            some as SOME thm1 =>
  1067                (case rewritec (prover, maxidx) ctxt (Thm.rhs_of thm1) of
  1070              (case rewritec (prover, maxidx) ctxt (Thm.rhs_of thm1) of
  1068                   SOME (thm2, skel2) =>
  1071                 SOME (thm2, skel2) =>
  1069                     transitive2 (Thm.transitive thm1 thm2)
  1072                   transitive2 (Thm.transitive thm1 thm2)
  1070                       (botc skel2 ctxt (Thm.rhs_of thm2))
       
  1071                 | NONE => some)
       
  1072            | NONE =>
       
  1073                (case rewritec (prover, maxidx) ctxt t of
       
  1074                   SOME (thm2, skel2) => transitive2 thm2
       
  1075                     (botc skel2 ctxt (Thm.rhs_of thm2))
  1073                     (botc skel2 ctxt (Thm.rhs_of thm2))
  1076                 | NONE => NONE))
  1074               | NONE => some)
       
  1075          | NONE =>
       
  1076              (case rewritec (prover, maxidx) ctxt t of
       
  1077                 SOME (thm2, skel2) => transitive2 thm2
       
  1078                   (botc skel2 ctxt (Thm.rhs_of thm2))
       
  1079               | NONE => NONE))
  1077 
  1080 
  1078     and try_botc ctxt t =
  1081     and try_botc ctxt t =
  1079           (case botc skel0 ctxt t of
  1082       (case botc skel0 ctxt t of
  1080             SOME trec1 => trec1
  1083         SOME trec1 => trec1
  1081           | NONE => (Thm.reflexive t))
  1084       | NONE => Thm.reflexive t)
  1082 
  1085 
  1083     and subc skel ctxt t0 =
  1086     and subc skel ctxt t0 =
  1084         let val Simpset ({bounds, ...}, {congs, ...}) = simpset_of ctxt in
  1087         let val Simpset ({bounds, ...}, {congs, ...}) = simpset_of ctxt in
  1085           (case term_of t0 of
  1088           (case term_of t0 of
  1086               Abs (a, T, _) =>
  1089               Abs (a, T, _) =>
  1092                       if b <> b' then
  1095                       if b <> b' then
  1093                         warning ("Simplifier: renamed bound variable " ^
  1096                         warning ("Simplifier: renamed bound variable " ^
  1094                           quote b ^ " to " ^ quote b' ^ Position.here (Position.thread_data ()))
  1097                           quote b ^ " to " ^ quote b' ^ Position.here (Position.thread_data ()))
  1095                       else ();
  1098                       else ();
  1096                     val ctxt' = add_bound ((b', T), a) ctxt;
  1099                     val ctxt' = add_bound ((b', T), a) ctxt;
  1097                     val skel' = case skel of Abs (_, _, sk) => sk | _ => skel0;
  1100                     val skel' = (case skel of Abs (_, _, sk) => sk | _ => skel0);
  1098                 in
  1101                 in
  1099                   (case botc skel' ctxt' t' of
  1102                   (case botc skel' ctxt' t' of
  1100                     SOME thm => SOME (Thm.abstract_rule a v thm)
  1103                     SOME thm => SOME (Thm.abstract_rule a v thm)
  1101                   | NONE => NONE)
  1104                   | NONE => NONE)
  1102                 end
  1105                 end
  1103             | t $ _ => (case t of
  1106             | t $ _ =>
       
  1107               (case t of
  1104                 Const ("==>", _) $ _  => impc t0 ctxt
  1108                 Const ("==>", _) $ _  => impc t0 ctxt
  1105               | Abs _ =>
  1109               | Abs _ =>
  1106                   let val thm = Thm.beta_conversion false t0
  1110                   let val thm = Thm.beta_conversion false t0
  1107                   in case subc skel0 ctxt (Thm.rhs_of thm) of
  1111                   in
  1108                        NONE => SOME thm
  1112                     (case subc skel0 ctxt (Thm.rhs_of thm) of
  1109                      | SOME thm' => SOME (Thm.transitive thm thm')
  1113                       NONE => SOME thm
       
  1114                     | SOME thm' => SOME (Thm.transitive thm thm'))
  1110                   end
  1115                   end
  1111               | _  =>
  1116               | _  =>
  1112                   let fun appc () =
  1117                   let fun appc () =
  1113                         let
  1118                         let
  1114                           val (tskel, uskel) = case skel of
  1119                           val (tskel, uskel) =
       
  1120                             (case skel of
  1115                               tskel $ uskel => (tskel, uskel)
  1121                               tskel $ uskel => (tskel, uskel)
  1116                             | _ => (skel0, skel0);
  1122                             | _ => (skel0, skel0));
  1117                           val (ct, cu) = Thm.dest_comb t0
  1123                           val (ct, cu) = Thm.dest_comb t0;
  1118                         in
  1124                         in
  1119                         (case botc tskel ctxt ct of
  1125                           (case botc tskel ctxt ct of
  1120                            SOME thm1 =>
  1126                             SOME thm1 =>
  1121                              (case botc uskel ctxt cu of
  1127                               (case botc uskel ctxt cu of
  1122                                 SOME thm2 => SOME (Thm.combination thm1 thm2)
  1128                                 SOME thm2 => SOME (Thm.combination thm1 thm2)
  1123                               | NONE => SOME (Thm.combination thm1 (Thm.reflexive cu)))
  1129                               | NONE => SOME (Thm.combination thm1 (Thm.reflexive cu)))
  1124                          | NONE =>
  1130                           | NONE =>
  1125                              (case botc uskel ctxt cu of
  1131                               (case botc uskel ctxt cu of
  1126                                 SOME thm1 => SOME (Thm.combination (Thm.reflexive ct) thm1)
  1132                                 SOME thm1 => SOME (Thm.combination (Thm.reflexive ct) thm1)
  1127                               | NONE => NONE))
  1133                               | NONE => NONE))
  1128                         end
  1134                         end
  1129                       val (h, ts) = strip_comb t
  1135                       val (h, ts) = strip_comb t;
  1130                   in case cong_name h of
  1136                   in
  1131                        SOME a =>
  1137                     (case cong_name h of
  1132                          (case AList.lookup (op =) (fst congs) a of
  1138                       SOME a =>
  1133                             NONE => appc ()
  1139                         (case AList.lookup (op =) (fst congs) a of
  1134                           | SOME cong =>
  1140                            NONE => appc ()
       
  1141                         | SOME cong =>
  1135      (*post processing: some partial applications h t1 ... tj, j <= length ts,
  1142      (*post processing: some partial applications h t1 ... tj, j <= length ts,
  1136        may be a redex. Example: map (%x. x) = (%xs. xs) wrt map_cong*)
  1143        may be a redex. Example: map (%x. x) = (%xs. xs) wrt map_cong*)
  1137                              (let
  1144                            (let
  1138                                 val thm = congc (prover ctxt) ctxt maxidx cong t0;
  1145                               val thm = congc (prover ctxt) ctxt maxidx cong t0;
  1139                                 val t = the_default t0 (Option.map Thm.rhs_of thm);
  1146                               val t = the_default t0 (Option.map Thm.rhs_of thm);
  1140                                 val (cl, cr) = Thm.dest_comb t
  1147                               val (cl, cr) = Thm.dest_comb t
  1141                                 val dVar = Var(("", 0), dummyT)
  1148                               val dVar = Var(("", 0), dummyT)
  1142                                 val skel =
  1149                               val skel =
  1143                                   list_comb (h, replicate (length ts) dVar)
  1150                                 list_comb (h, replicate (length ts) dVar)
  1144                               in case botc skel ctxt cl of
  1151                             in
  1145                                    NONE => thm
  1152                               (case botc skel ctxt cl of
  1146                                  | SOME thm' => transitive3 thm
  1153                                 NONE => thm
  1147                                      (Thm.combination thm' (Thm.reflexive cr))
  1154                               | SOME thm' =>
  1148                               end handle Pattern.MATCH => appc ()))
  1155                                   transitive3 thm (Thm.combination thm' (Thm.reflexive cr)))
  1149                      | _ => appc ()
  1156                             end handle Pattern.MATCH => appc ()))
       
  1157                      | _ => appc ())
  1150                   end)
  1158                   end)
  1151             | _ => NONE)
  1159             | _ => NONE)
  1152         end
  1160         end
  1153     and impc ct ctxt =
  1161     and impc ct ctxt =
  1154       if mutsimp then mut_impc0 [] ct [] [] ctxt else nonmut_impc ct ctxt
  1162       if mutsimp then mut_impc0 [] ct [] [] ctxt
       
  1163       else nonmut_impc ct ctxt
  1155 
  1164 
  1156     and rules_of_prem ctxt prem =
  1165     and rules_of_prem ctxt prem =
  1157       if maxidx_of_term (term_of prem) <> ~1
  1166       if maxidx_of_term (term_of prem) <> ~1
  1158       then (trace_cterm ctxt true
  1167       then (trace_cterm ctxt true
  1159         (fn () => "Cannot add premise as rewrite rule because it contains (type) unknowns:")
  1168         (fn () => "Cannot add premise as rewrite rule because it contains (type) unknowns:")
  1169       let
  1178       let
  1170         val (lhs, rhs) = Thm.dest_equals (Thm.cprop_of eq);
  1179         val (lhs, rhs) = Thm.dest_equals (Thm.cprop_of eq);
  1171         val eq' = Thm.implies_elim (Thm.instantiate
  1180         val eq' = Thm.implies_elim (Thm.instantiate
  1172           ([], [(cA, prem), (cB, lhs), (cC, rhs)]) Drule.imp_cong)
  1181           ([], [(cA, prem), (cB, lhs), (cC, rhs)]) Drule.imp_cong)
  1173           (Thm.implies_intr prem eq)
  1182           (Thm.implies_intr prem eq)
  1174       in if not r then eq' else
  1183       in
  1175         let
  1184         if not r then eq'
  1176           val (prem', concl) = Thm.dest_implies lhs;
  1185         else
  1177           val (prem'', _) = Thm.dest_implies rhs
  1186           let
  1178         in Thm.transitive (Thm.transitive
  1187             val (prem', concl) = Thm.dest_implies lhs;
  1179           (Thm.instantiate ([], [(cA, prem'), (cB, prem), (cC, concl)])
  1188             val (prem'', _) = Thm.dest_implies rhs
  1180              Drule.swap_prems_eq) eq')
  1189           in Thm.transitive (Thm.transitive
  1181           (Thm.instantiate ([], [(cA, prem), (cB, prem''), (cC, concl)])
  1190             (Thm.instantiate ([], [(cA, prem'), (cB, prem), (cC, concl)])
  1182              Drule.swap_prems_eq)
  1191                Drule.swap_prems_eq) eq')
  1183         end
  1192             (Thm.instantiate ([], [(cA, prem), (cB, prem''), (cC, concl)])
       
  1193                Drule.swap_prems_eq)
       
  1194           end
  1184       end
  1195       end
  1185 
  1196 
  1186     and rebuild [] _ _ _ _ eq = eq
  1197     and rebuild [] _ _ _ _ eq = eq
  1187       | rebuild (prem :: prems) concl (_ :: rrss) (_ :: asms) ctxt eq =
  1198       | rebuild (prem :: prems) concl (_ :: rrss) (_ :: asms) ctxt eq =
  1188           let
  1199           let
  1216            else rebuild prems' concl rrss' asms' ctxt
  1227            else rebuild prems' concl rrss' asms' ctxt
  1217              (botc skel0 (add_rrules (rev rrss', rev asms') ctxt) concl))
  1228              (botc skel0 (add_rrules (rev rrss', rev asms') ctxt) concl))
  1218 
  1229 
  1219       | mut_impc (prem :: prems) concl (rrs :: rrss) (asm :: asms)
  1230       | mut_impc (prem :: prems) concl (rrs :: rrss) (asm :: asms)
  1220           prems' rrss' asms' eqns ctxt changed k =
  1231           prems' rrss' asms' eqns ctxt changed k =
  1221         case (if k = 0 then NONE else botc skel0 (add_rrules
  1232         (case (if k = 0 then NONE else botc skel0 (add_rrules
  1222           (rev rrss' @ rrss, rev asms' @ asms) ctxt) prem) of
  1233           (rev rrss' @ rrss, rev asms' @ asms) ctxt) prem) of
  1223             NONE => mut_impc prems concl rrss asms (prem :: prems')
  1234             NONE => mut_impc prems concl rrss asms (prem :: prems')
  1224               (rrs :: rrss') (asm :: asms') (NONE :: eqns) ctxt changed
  1235               (rrs :: rrss') (asm :: asms') (NONE :: eqns) ctxt changed
  1225               (if k = 0 then 0 else k - 1)
  1236               (if k = 0 then 0 else k - 1)
  1226           | SOME eqn =>
  1237         | SOME eqn =>
  1227             let
  1238             let
  1228               val prem' = Thm.rhs_of eqn;
  1239               val prem' = Thm.rhs_of eqn;
  1229               val tprems = map term_of prems;
  1240               val tprems = map term_of prems;
  1230               val i = 1 + fold Integer.max (map (fn p =>
  1241               val i = 1 + fold Integer.max (map (fn p =>
  1231                 find_index (fn q => q aconv p) tprems) (Thm.hyps_of eqn)) ~1;
  1242                 find_index (fn q => q aconv p) tprems) (Thm.hyps_of eqn)) ~1;
  1232               val (rrs', asm') = rules_of_prem ctxt prem';
  1243               val (rrs', asm') = rules_of_prem ctxt prem';
  1233             in mut_impc prems concl rrss asms (prem' :: prems')
  1244             in
  1234               (rrs' :: rrss') (asm' :: asms') (SOME (fold_rev (disch true)
  1245               mut_impc prems concl rrss asms (prem' :: prems')
  1235                 (take i prems)
  1246                 (rrs' :: rrss') (asm' :: asms')
  1236                 (Drule.imp_cong_rule eqn (Thm.reflexive (Drule.list_implies
  1247                 (SOME (fold_rev (disch true)
  1237                   (drop i prems, concl))))) :: eqns)
  1248                   (take i prems)
  1238                   ctxt (length prems') ~1
  1249                   (Drule.imp_cong_rule eqn (Thm.reflexive (Drule.list_implies
  1239             end
  1250                     (drop i prems, concl))))) :: eqns)
  1240 
  1251                 ctxt (length prems') ~1
  1241      (*legacy code - only for backwards compatibility*)
  1252             end)
       
  1253 
       
  1254     (*legacy code -- only for backwards compatibility*)
  1242     and nonmut_impc ct ctxt =
  1255     and nonmut_impc ct ctxt =
  1243       let
  1256       let
  1244         val (prem, conc) = Thm.dest_implies ct;
  1257         val (prem, conc) = Thm.dest_implies ct;
  1245         val thm1 = if simprem then botc skel0 ctxt prem else NONE;
  1258         val thm1 = if simprem then botc skel0 ctxt prem else NONE;
  1246         val prem1 = the_default prem (Option.map Thm.rhs_of thm1);
  1259         val prem1 = the_default prem (Option.map Thm.rhs_of thm1);
  1258               (case thm1 of
  1271               (case thm1 of
  1259                 NONE => SOME thm2'
  1272                 NONE => SOME thm2'
  1260               | SOME thm1' =>
  1273               | SOME thm1' =>
  1261                  SOME (Thm.transitive (Drule.imp_cong_rule thm1' (Thm.reflexive conc)) thm2'))
  1274                  SOME (Thm.transitive (Drule.imp_cong_rule thm1' (Thm.reflexive conc)) thm2'))
  1262             end)
  1275             end)
  1263       end
  1276       end;
  1264 
  1277 
  1265  in try_botc end;
  1278   in try_botc end;
  1266 
  1279 
  1267 
  1280 
  1268 (* Meta-rewriting: rewrites t to u and returns the theorem t==u *)
  1281 (* Meta-rewriting: rewrites t to u and returns the theorem t==u *)
  1269 
  1282 
  1270 (*
  1283 (*