| author | haftmann | 
| Mon, 20 Jan 2025 22:15:11 +0100 | |
| changeset 81876 | ac0716ca151b | 
| parent 81253 | bbed9f218158 | 
| permissions | -rw-r--r-- | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 1 | (* Title: Pure/more_pattern.ML | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 2 | Author: Tobias Nipkow, TU Muenchen | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 3 | Author: Stefan Berghofer, TU Muenchen | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 4 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 5 | Add-ons to Higher-Order Patterns, outside the inference kernel. | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 6 | *) | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 7 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 8 | signature PATTERN = | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 9 | sig | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 10 | include PATTERN | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 11 | val matches: theory -> term * term -> bool | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 12 | val matchess: theory -> term list * term list -> bool | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 13 | val equiv: theory -> term * term -> bool | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 14 | val first_order: term -> bool | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 15 | val match_rew: theory -> term -> term * term -> (term * term) option | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 16 | val rewrite_term: theory -> (term * term) list -> (term -> term option) list -> term -> term | 
| 81253 
bbed9f218158
prefer rewrite_term_yoyo for improved performance and occasionally better results (conforming to Ast.normalize);
 wenzelm parents: 
81249diff
changeset | 17 | val rewrite_term_topdown: theory -> (term * term) list -> (term -> term option) list -> term -> term | 
| 81246 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 18 | val rewrite_term_yoyo: theory -> (term * term) list -> (term -> term option) list -> term -> term | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 19 | end; | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 20 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 21 | structure Pattern: PATTERN = | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 22 | struct | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 23 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 24 | fun matches thy po = | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 25 | (Pattern.match thy po (Vartab.empty, Vartab.empty); true) handle Pattern.MATCH => false; | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 26 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 27 | fun matchess thy (ps, os) = | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 28 | length ps = length os andalso | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 29 | ((fold (Pattern.match thy) (ps ~~ os) (Vartab.empty, Vartab.empty); true) | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 30 | handle Pattern.MATCH => false); | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 31 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 32 | fun equiv thy (t, u) = matches thy (t, u) andalso matches thy (u, t); | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 33 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 34 | fun first_order (Abs (_, _, t)) = first_order t | 
| 59027 | 35 | | first_order (Var _ $ _) = false | 
| 36 | | first_order (t $ u) = first_order t andalso first_order u | |
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 37 | | first_order _ = true; | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 38 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 39 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 40 | (* rewriting -- simple but fast *) | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 41 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 42 | fun match_rew thy tm (tm1, tm2) = | 
| 79242 | 43 | let val rtm = perhaps (Term.rename_abs tm1 tm) tm2 in | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 44 | SOME (Envir.subst_term (Pattern.match thy (tm1, tm) (Vartab.empty, Vartab.empty)) rtm, rtm) | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 45 | handle Pattern.MATCH => NONE | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 46 | end; | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 47 | |
| 81243 | 48 | local | 
| 49 | ||
| 50 | val skel0 = Bound 0; | |
| 51 | val skel_fun = fn skel $ _ => skel | _ => skel0; | |
| 52 | val skel_arg = fn _ $ skel => skel | _ => skel0; | |
| 53 | val skel_body = fn Abs (_, _, skel) => skel | _ => skel0; | |
| 54 | ||
| 81246 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 55 | datatype mode = Bottom | Top | Yoyo; | 
| 81245 | 56 | |
| 81249 | 57 | fun rewrite_term_mode mode thy rules procs = | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 58 | let | 
| 74525 
c960bfcb91db
discontinued Term.dest_abs / Logic.dest_all, which are officially superseded by Variable.dest_abs etc., but there are also Term.dest_abs_global to recover existing tools easily;
 wenzelm parents: 
70443diff
changeset | 59 | fun variant_absfree bounds x tm = | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 60 | let | 
| 74525 
c960bfcb91db
discontinued Term.dest_abs / Logic.dest_all, which are officially superseded by Variable.dest_abs etc., but there are also Term.dest_abs_global to recover existing tools easily;
 wenzelm parents: 
70443diff
changeset | 61 | val ((x', T), t') = | 
| 
c960bfcb91db
discontinued Term.dest_abs / Logic.dest_all, which are officially superseded by Variable.dest_abs etc., but there are also Term.dest_abs_global to recover existing tools easily;
 wenzelm parents: 
70443diff
changeset | 62 | Term.dest_abs_fresh (Name.bound bounds) tm | 
| 
c960bfcb91db
discontinued Term.dest_abs / Logic.dest_all, which are officially superseded by Variable.dest_abs etc., but there are also Term.dest_abs_global to recover existing tools easily;
 wenzelm parents: 
70443diff
changeset | 63 | handle Term.USED_FREE _ => Term.dest_abs_global tm; (* FIXME proper context *) | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 64 | fun abs u = Abs (x, T, abstract_over (Free (x', T), u)); | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 65 | in (abs, t') end; | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 66 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 67 | fun rew (Abs (_, _, body) $ t) = SOME (subst_bound (t, body), skel0) | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 68 | | rew tm = | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 69 | (case get_first (match_rew thy tm) rules of | 
| 81242 | 70 | NONE => Option.map (rpair skel0) (get_first (fn proc => proc tm) procs) | 
| 71 | | some => some); | |
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 72 | |
| 81244 | 73 | fun rew_sub rw bounds _ (Abs (_, _, body) $ t) = | 
| 81242 | 74 | let val t' = subst_bound (t, body) | 
| 81247 
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
 wenzelm parents: 
81246diff
changeset | 75 | in SOME (perhaps (rew_sub rw bounds skel0) t') end | 
| 81244 | 76 | | rew_sub rw bounds skel (t $ u) = | 
| 77 | (case (rw bounds (skel_fun skel) t, rw bounds (skel_arg skel) u) of | |
| 78 | (SOME t', SOME u') => SOME (t' $ u') | |
| 79 | | (SOME t', NONE) => SOME (t' $ u) | |
| 80 | | (NONE, SOME u') => SOME (t $ u') | |
| 81 | | (NONE, NONE) => NONE) | |
| 82 | | rew_sub rw bounds skel (t as Abs (x, _, _)) = | |
| 83 | let val (abs, t') = variant_absfree bounds x t | |
| 84 | in Option.map abs (rw (bounds + 1) (skel_body skel) t') end | |
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 85 | | rew_sub _ _ _ _ = NONE; | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 86 | |
| 81246 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 87 | |
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 88 | (* bottom-up with skeleton *) | 
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 89 | |
| 81245 | 90 | fun rew_bottom _ (Var _) _ = NONE | 
| 91 | | rew_bottom bounds skel t = | |
| 92 | (case rew_sub rew_bottom bounds skel t of | |
| 81244 | 93 | SOME t1 => | 
| 94 | (case rew t1 of | |
| 81247 
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
 wenzelm parents: 
81246diff
changeset | 95 | SOME (t2, skel') => SOME (perhaps (rew_bottom bounds skel') t2) | 
| 81244 | 96 | | NONE => SOME t1) | 
| 97 | | NONE => | |
| 98 | (case rew t of | |
| 81247 
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
 wenzelm parents: 
81246diff
changeset | 99 | SOME (t1, skel') => SOME (perhaps (rew_bottom bounds skel') t1) | 
| 81219 | 100 | | NONE => NONE)); | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 101 | |
| 81246 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 102 | |
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 103 | (* top-down *) | 
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 104 | |
| 81244 | 105 | fun rew_top bounds _ t = | 
| 106 | (case rew t of | |
| 107 | SOME (t1, _) => | |
| 108 | (case rew_sub rew_top bounds skel0 t1 of | |
| 81247 
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
 wenzelm parents: 
81246diff
changeset | 109 | SOME t2 => SOME (perhaps (rew_top bounds skel0) t2) | 
| 81244 | 110 | | NONE => SOME t1) | 
| 81219 | 111 | | NONE => | 
| 81244 | 112 | (case rew_sub rew_top bounds skel0 t of | 
| 81247 
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
 wenzelm parents: 
81246diff
changeset | 113 | SOME t1 => SOME (perhaps (rew_top bounds skel0) t1) | 
| 81219 | 114 | | NONE => NONE)); | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 115 | |
| 81246 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 116 | |
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 117 | (* yoyo: see also Ast.normalize *) | 
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 118 | |
| 81247 
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
 wenzelm parents: 
81246diff
changeset | 119 | val rew_yoyo1 = perhaps_loop (rew #> Option.map #1); | 
| 81246 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 120 | |
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 121 | fun rew_yoyo2 bounds _ t = | 
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 122 | (case rew_yoyo1 t of | 
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 123 | SOME t1 => | 
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 124 | (case rew_sub rew_yoyo2 bounds skel0 t1 of | 
| 81247 
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
 wenzelm parents: 
81246diff
changeset | 125 | SOME t2 => SOME (perhaps rew_yoyo1 t2) | 
| 81246 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 126 | | NONE => SOME t1) | 
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 127 | | NONE => | 
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 128 | (case rew_sub rew_yoyo2 bounds skel0 t of | 
| 81247 
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
 wenzelm parents: 
81246diff
changeset | 129 | SOME t1 => SOME (perhaps rew_yoyo1 t1) | 
| 81246 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 130 | | NONE => NONE)); | 
| 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 131 | |
| 81247 
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
 wenzelm parents: 
81246diff
changeset | 132 | fun rew_yoyo bounds skel = perhaps_loop (rew_yoyo2 bounds skel); | 
| 81249 | 133 | in | 
| 134 | perhaps ((case mode of Bottom => rew_bottom | Top => rew_top | Yoyo => rew_yoyo) 0 skel0) | |
| 135 | end; | |
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 136 | |
| 81243 | 137 | in | 
| 138 | ||
| 81245 | 139 | val rewrite_term = rewrite_term_mode Bottom; | 
| 81253 
bbed9f218158
prefer rewrite_term_yoyo for improved performance and occasionally better results (conforming to Ast.normalize);
 wenzelm parents: 
81249diff
changeset | 140 | val rewrite_term_topdown = rewrite_term_mode Top; | 
| 81246 
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
 wenzelm parents: 
81245diff
changeset | 141 | val rewrite_term_yoyo = rewrite_term_mode Yoyo; | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 142 | |
| 81243 | 143 | end; | 
| 59026 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 144 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 145 | open Pattern; | 
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 146 | |
| 
30b8a5825a9c
removed some add-ons from modules that are relevant for the inference kernel;
 wenzelm parents: diff
changeset | 147 | end; |