author | desharna |
Fri, 04 Apr 2025 15:30:03 +0200 | |
changeset 82399 | 9d457dfb56c5 |
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:
81249
diff
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:
81245
diff
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:
81245
diff
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:
70443
diff
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:
70443
diff
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:
70443
diff
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:
70443
diff
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:
81246
diff
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:
81245
diff
changeset
|
87 |
|
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
88 |
(* bottom-up with skeleton *) |
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
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:
81246
diff
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:
81246
diff
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:
81245
diff
changeset
|
102 |
|
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
103 |
(* top-down *) |
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
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:
81246
diff
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:
81246
diff
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:
81245
diff
changeset
|
116 |
|
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
117 |
(* yoyo: see also Ast.normalize *) |
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
118 |
|
81247
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
wenzelm
parents:
81246
diff
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:
81245
diff
changeset
|
120 |
|
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
121 |
fun rew_yoyo2 bounds _ t = |
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
122 |
(case rew_yoyo1 t of |
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
123 |
SOME t1 => |
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
124 |
(case rew_sub rew_yoyo2 bounds skel0 t1 of |
81247
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
wenzelm
parents:
81246
diff
changeset
|
125 |
SOME t2 => SOME (perhaps rew_yoyo1 t2) |
81246
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
126 |
| NONE => SOME t1) |
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
127 |
| NONE => |
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
128 |
(case rew_sub rew_yoyo2 bounds skel0 t of |
81247
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
wenzelm
parents:
81246
diff
changeset
|
129 |
SOME t1 => SOME (perhaps rew_yoyo1 t1) |
81246
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
130 |
| NONE => NONE)); |
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
changeset
|
131 |
|
81247
b162ff88bdc5
misc tuning: more concise (or hermetic) pointfree style;
wenzelm
parents:
81246
diff
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:
81249
diff
changeset
|
140 |
val rewrite_term_topdown = rewrite_term_mode Top; |
81246
7d61f448f693
provide rewrite_term_yoyo, which is analogous to Ast.normalize;
wenzelm
parents:
81245
diff
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; |