author | wenzelm |
Thu, 05 Jan 2012 18:18:39 +0100 | |
changeset 46125 | 00cd193a48dc |
parent 46059 | f805747f8571 |
child 46135 | 6bff2ebaf7bb |
permissions | -rw-r--r-- |
33968
f94fb13ecbb3
modernized structures and tuned headers of datatype package modules; joined former datatype.ML and datatype_rep_proofs.ML
haftmann
parents:
33040
diff
changeset
|
1 |
(* Title: HOL/Tools/Datatype/datatype_case.ML |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
2 |
Author: Konrad Slind, Cambridge University Computer Laboratory |
29266 | 3 |
Author: Stefan Berghofer, TU Muenchen |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
4 |
|
33968
f94fb13ecbb3
modernized structures and tuned headers of datatype package modules; joined former datatype.ML and datatype_rep_proofs.ML
haftmann
parents:
33040
diff
changeset
|
5 |
Datatype package: nested case expressions on datatypes. |
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
6 |
|
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
7 |
TODO: generic tool with separate data slot, without hard-wiring the |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
8 |
datatype package. |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
9 |
*) |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
10 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
11 |
signature DATATYPE_CASE = |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
12 |
sig |
33968
f94fb13ecbb3
modernized structures and tuned headers of datatype package modules; joined former datatype.ML and datatype_rep_proofs.ML
haftmann
parents:
33040
diff
changeset
|
13 |
datatype config = Error | Warning | Quiet |
f94fb13ecbb3
modernized structures and tuned headers of datatype package modules; joined former datatype.ML and datatype_rep_proofs.ML
haftmann
parents:
33040
diff
changeset
|
14 |
type info = Datatype_Aux.info |
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
15 |
val make_case : Proof.context -> config -> string list -> term -> (term * term) list -> term |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
16 |
val strip_case : Proof.context -> bool -> term -> (term * (term * term) list) option |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
17 |
val case_tr: bool -> Proof.context -> term list -> term |
46003
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
18 |
val show_cases: bool Config.T |
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
19 |
val case_tr': string -> Proof.context -> term list -> term |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
20 |
val add_case_tr' : string list -> theory -> theory |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
21 |
val setup: theory -> theory |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
22 |
end; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
23 |
|
33968
f94fb13ecbb3
modernized structures and tuned headers of datatype package modules; joined former datatype.ML and datatype_rep_proofs.ML
haftmann
parents:
33040
diff
changeset
|
24 |
structure Datatype_Case : DATATYPE_CASE = |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
25 |
struct |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
26 |
|
32671 | 27 |
datatype config = Error | Warning | Quiet; |
33968
f94fb13ecbb3
modernized structures and tuned headers of datatype package modules; joined former datatype.ML and datatype_rep_proofs.ML
haftmann
parents:
33040
diff
changeset
|
28 |
type info = Datatype_Aux.info; |
32671 | 29 |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
30 |
exception CASE_ERROR of string * int; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
31 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
32 |
fun match_type thy pat ob = Sign.typ_match thy (pat, ob) Vartab.empty; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
33 |
|
43255 | 34 |
(* Get information about datatypes *) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
35 |
|
45894 | 36 |
fun ty_info ({descr, case_name, index, ...} : info) = |
37 |
let |
|
38 |
val (_, (tname, dts, constrs)) = nth descr index; |
|
39 |
val mk_ty = Datatype_Aux.typ_of_dtyp descr; |
|
40 |
val T = Type (tname, map mk_ty dts); |
|
41 |
in |
|
42 |
{case_name = case_name, |
|
43 |
constructors = map (fn (cname, dts') => |
|
44 |
Const (cname, Logic.varifyT_global (map mk_ty dts' ---> T))) constrs} |
|
45 |
end; |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
46 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
47 |
|
43255 | 48 |
(*Each pattern carries with it a tag i, which denotes the clause it |
49 |
came from. i = ~1 indicates that the clause was added by pattern |
|
50 |
completion.*) |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
51 |
|
29281 | 52 |
fun add_row_used ((prfx, pats), (tm, tag)) = |
43252 | 53 |
fold Term.add_free_names (tm :: pats @ map Free prfx); |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
54 |
|
43255 | 55 |
(*try to preserve names given by user*) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
56 |
fun default_names names ts = |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
57 |
map (fn ("", Free (name', _)) => name' | (name, _) => name) (names ~~ ts); |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
58 |
|
35124 | 59 |
fun strip_constraints (Const (@{syntax_const "_constrain"}, _) $ t $ tT) = |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
60 |
strip_constraints t ||> cons tT |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
61 |
| strip_constraints t = (t, []); |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
62 |
|
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
63 |
fun constrain_Abs tT t = Syntax.const @{syntax_const "_constrainAbs"} $ t $ tT; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
64 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
65 |
|
43255 | 66 |
(*Produce an instance of a constructor, plus fresh variables for its arguments.*) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
67 |
fun fresh_constr ty_match ty_inst colty used c = |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
68 |
let |
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
69 |
val (_, T) = dest_Const c; |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
70 |
val Ts = binder_types T; |
45700 | 71 |
val names = |
72 |
Name.variant_list used (Datatype_Prop.make_tnames (map Logic.unvarifyT_global Ts)); |
|
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
73 |
val ty = body_type T; |
45700 | 74 |
val ty_theta = ty_match ty colty |
75 |
handle Type.TYPE_MATCH => raise CASE_ERROR ("type mismatch", ~1); |
|
76 |
val c' = ty_inst ty_theta c; |
|
77 |
val gvars = map (ty_inst ty_theta o Free) (names ~~ Ts); |
|
42049 | 78 |
in (c', gvars) end; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
79 |
|
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
80 |
fun strip_comb_positions tm = |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
81 |
let |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
82 |
fun result t ts = (Term_Position.strip_positions t, ts); |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
83 |
fun strip (t as (Const (@{syntax_const "_constrain"}, _) $ _ $ _)) ts = result t ts |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
84 |
| strip (f $ t) ts = strip f (t :: ts) |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
85 |
| strip t ts = result t ts; |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
86 |
in strip tm [] end; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
87 |
|
45889 | 88 |
(*Go through a list of rows and pick out the ones beginning with a |
45700 | 89 |
pattern with constructor = name.*) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
90 |
fun mk_group (name, T) rows = |
42049 | 91 |
let val k = length (binder_types T) in |
43256 | 92 |
fold (fn (row as ((prfx, p :: ps), rhs as (_, i))) => |
42049 | 93 |
fn ((in_group, not_in_group), (names, cnstrts)) => |
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
94 |
(case strip_comb_positions p of |
42049 | 95 |
(Const (name', _), args) => |
96 |
if name = name' then |
|
97 |
if length args = k then |
|
45700 | 98 |
let val (args', cnstrts') = split_list (map strip_constraints args) in |
43256 | 99 |
((((prfx, args' @ ps), rhs) :: in_group, not_in_group), |
42049 | 100 |
(default_names names args', map2 append cnstrts cnstrts')) |
101 |
end |
|
45700 | 102 |
else raise CASE_ERROR ("Wrong number of arguments for constructor " ^ name, i) |
42049 | 103 |
else ((in_group, row :: not_in_group), (names, cnstrts)) |
104 |
| _ => raise CASE_ERROR ("Not a constructor pattern", i))) |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
105 |
rows (([], []), (replicate k "", replicate k [])) |>> pairself rev |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
106 |
end; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
107 |
|
43255 | 108 |
|
109 |
(* Partitioning *) |
|
110 |
||
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
111 |
fun partition _ _ _ _ _ _ _ [] = raise CASE_ERROR ("partition: no rows", ~1) |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
112 |
| partition ty_match ty_inst type_of used constructors colty res_ty |
43256 | 113 |
(rows as (((prfx, _ :: ps), _) :: _)) = |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
114 |
let |
43257
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
115 |
fun part [] [] = [] |
45700 | 116 |
| part [] ((_, (_, i)) :: _) = raise CASE_ERROR ("Not a constructor pattern", i) |
43257
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
117 |
| part (c :: cs) rows = |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
118 |
let |
45700 | 119 |
val ((in_group, not_in_group), (names, cnstrts)) = mk_group (dest_Const c) rows; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
120 |
val used' = fold add_row_used in_group used; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
121 |
val (c', gvars) = fresh_constr ty_match ty_inst colty used' c; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
122 |
val in_group' = |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
123 |
if null in_group (* Constructor not given *) |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
124 |
then |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
125 |
let |
43256 | 126 |
val Ts = map type_of ps; |
45700 | 127 |
val xs = |
128 |
Name.variant_list |
|
129 |
(fold Term.add_free_names gvars used') |
|
130 |
(replicate (length ps) "x"); |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
131 |
in |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
132 |
[((prfx, gvars @ map Free (xs ~~ Ts)), |
43254 | 133 |
(Const (@{const_syntax undefined}, res_ty), ~1))] |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
134 |
end |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
135 |
else in_group |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
136 |
in |
43257
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
137 |
{constructor = c', |
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
138 |
new_formals = gvars, |
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
139 |
names = names, |
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
140 |
constraints = cnstrts, |
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
141 |
group = in_group'} :: part cs not_in_group |
45898 | 142 |
end; |
43257
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
143 |
in part constructors rows end; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
144 |
|
45700 | 145 |
fun v_to_prfx (prfx, Free v :: pats) = (v :: prfx, pats) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
146 |
| v_to_prfx _ = raise CASE_ERROR ("mk_case: v_to_prfx", ~1); |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
147 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
148 |
|
43255 | 149 |
(* Translation of pattern terms into nested case expressions. *) |
45700 | 150 |
|
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
151 |
fun mk_case ctxt ty_match ty_inst type_of used range_ty = |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
152 |
let |
45894 | 153 |
val get_info = Datatype_Data.info_of_constr_permissive (Proof_Context.theory_of ctxt); |
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
154 |
|
45700 | 155 |
fun expand constructors used ty ((_, []), _) = raise CASE_ERROR ("mk_case: expand_var_row", ~1) |
43256 | 156 |
| expand constructors used ty (row as ((prfx, p :: ps), (rhs, tag))) = |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
157 |
if is_Free p then |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
158 |
let |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
159 |
val used' = add_row_used row used; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
160 |
fun expnd c = |
45700 | 161 |
let val capp = list_comb (fresh_constr ty_match ty_inst ty used' c) |
162 |
in ((prfx, capp :: ps), (subst_free [(p, capp)] rhs, tag)) end |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
163 |
in map expnd constructors end |
45898 | 164 |
else [row]; |
165 |
||
166 |
val name = singleton (Name.variant_list used) "a"; |
|
167 |
||
43257
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
168 |
fun mk _ [] = raise CASE_ERROR ("no rows", ~1) |
45700 | 169 |
| mk [] (((_, []), (tm, tag)) :: _) = ([tag], tm) (* Done *) |
170 |
| mk path (rows as ((row as ((_, [Free _]), _)) :: _ :: _)) = mk path [row] |
|
43257
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
171 |
| mk (u :: us) (rows as ((_, _ :: _), _) :: _) = |
43254 | 172 |
let val col0 = map (fn ((_, p :: _), (_, i)) => (p, i)) rows in |
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
173 |
(case Option.map (apfst (fst o strip_comb_positions)) |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
174 |
(find_first (not o is_Free o fst) col0) of |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
175 |
NONE => |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
176 |
let |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
177 |
val rows' = map (fn ((v, _), row) => row ||> |
43255 | 178 |
apfst (subst_free [(v, u)]) |>> v_to_prfx) (col0 ~~ rows); |
43257
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
179 |
in mk us rows' end |
42049 | 180 |
| SOME (Const (cname, cT), i) => |
45894 | 181 |
(case Option.map ty_info (get_info (cname, cT)) of |
42049 | 182 |
NONE => raise CASE_ERROR ("Not a datatype constructor: " ^ cname, i) |
183 |
| SOME {case_name, constructors} => |
|
45700 | 184 |
let |
185 |
val pty = body_type cT; |
|
186 |
val used' = fold Term.add_free_names us used; |
|
187 |
val nrows = maps (expand constructors used' pty) rows; |
|
188 |
val subproblems = |
|
189 |
partition ty_match ty_inst type_of used' |
|
190 |
constructors pty range_ty nrows; |
|
191 |
val (pat_rect, dtrees) = |
|
192 |
split_list (map (fn {new_formals, group, ...} => |
|
193 |
mk (new_formals @ us) group) subproblems); |
|
194 |
val case_functions = |
|
195 |
map2 (fn {new_formals, names, constraints, ...} => |
|
196 |
fold_rev (fn ((x as Free (_, T), s), cnstrts) => fn t => |
|
197 |
Abs (if s = "" then name else s, T, abstract_over (x, t)) |
|
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
198 |
|> fold constrain_Abs cnstrts) (new_formals ~~ names ~~ constraints)) |
45700 | 199 |
subproblems dtrees; |
200 |
val types = map type_of (case_functions @ [u]); |
|
201 |
val case_const = Const (case_name, types ---> range_ty); |
|
202 |
val tree = list_comb (case_const, case_functions @ [u]); |
|
203 |
in (flat pat_rect, tree) end) |
|
204 |
| SOME (t, i) => |
|
205 |
raise CASE_ERROR ("Not a datatype constructor: " ^ Syntax.string_of_term ctxt t, i)) |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
206 |
end |
43257
b81fd5c8f2dc
eliminated unnecessary tail-recursion and funny use of records as 'named arguments' for functions
krauss
parents:
43256
diff
changeset
|
207 |
| mk _ _ = raise CASE_ERROR ("Malformed row matrix", ~1) |
42049 | 208 |
in mk end; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
209 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
210 |
fun case_error s = error ("Error in case expression:\n" ^ s); |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
211 |
|
45889 | 212 |
local |
213 |
||
43255 | 214 |
(*Repeated variable occurrences in a pattern are not allowed.*) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
215 |
fun no_repeat_vars ctxt pat = fold_aterms |
45700 | 216 |
(fn x as Free (s, _) => |
45889 | 217 |
(fn xs => |
218 |
if member op aconv xs x then |
|
219 |
case_error (quote s ^ " occurs repeatedly in the pattern " ^ |
|
220 |
quote (Syntax.string_of_term ctxt pat)) |
|
221 |
else x :: xs) |
|
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
222 |
| _ => I) (Term_Position.strip_positions pat) []; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
223 |
|
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
224 |
fun gen_make_case ty_match ty_inst type_of ctxt config used x clauses = |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
225 |
let |
35124 | 226 |
fun string_of_clause (pat, rhs) = |
227 |
Syntax.string_of_term ctxt (Syntax.const @{syntax_const "_case1"} $ pat $ rhs); |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
228 |
val _ = map (no_repeat_vars ctxt o fst) clauses; |
45700 | 229 |
val rows = map_index (fn (i, (pat, rhs)) => (([], [pat]), (rhs, i))) clauses; |
35124 | 230 |
val rangeT = |
45700 | 231 |
(case distinct (op =) (map (type_of o snd) clauses) of |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
232 |
[] => case_error "no clauses given" |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
233 |
| [T] => T |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
234 |
| _ => case_error "all cases must have the same result type"); |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
235 |
val used' = fold add_row_used rows used; |
45700 | 236 |
val (tags, case_tm) = |
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
237 |
mk_case ctxt ty_match ty_inst type_of used' rangeT [x] rows |
45700 | 238 |
handle CASE_ERROR (msg, i) => |
239 |
case_error |
|
240 |
(msg ^ (if i < 0 then "" else "\nIn clause\n" ^ string_of_clause (nth clauses i))); |
|
35124 | 241 |
val _ = |
43254 | 242 |
(case subtract (op =) tags (map (snd o snd) rows) of |
42049 | 243 |
[] => () |
244 |
| is => |
|
45700 | 245 |
(case config of Error => case_error | Warning => warning | Quiet => fn _ => ()) |
42049 | 246 |
("The following clauses are redundant (covered by preceding clauses):\n" ^ |
45700 | 247 |
cat_lines (map (string_of_clause o nth clauses) is))); |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
248 |
in |
43253
fa3c61dc9f2c
removed generation of instantiated pattern set, which is never actually used
krauss
parents:
43252
diff
changeset
|
249 |
case_tm |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
250 |
end; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
251 |
|
45889 | 252 |
in |
253 |
||
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
254 |
fun make_case ctxt = |
45700 | 255 |
gen_make_case (match_type (Proof_Context.theory_of ctxt)) |
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
256 |
Envir.subst_term_types fastype_of ctxt; |
45700 | 257 |
|
258 |
val make_case_untyped = |
|
259 |
gen_make_case (K (K Vartab.empty)) (K (Term.map_types (K dummyT))) (K dummyT); |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
260 |
|
45889 | 261 |
end; |
262 |
||
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
263 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
264 |
(* parse translation *) |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
265 |
|
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
266 |
fun case_tr err ctxt [t, u] = |
42049 | 267 |
let |
42361 | 268 |
val thy = Proof_Context.theory_of ctxt; |
269 |
val intern_const_syntax = Consts.intern_syntax (Proof_Context.consts_of ctxt); |
|
35256 | 270 |
|
42049 | 271 |
(* replace occurrences of dummy_pattern by distinct variables *) |
272 |
(* internalize constant names *) |
|
43324
2b47822868e4
discontinued Name.variant to emphasize that this is old-style / indirect;
wenzelm
parents:
43257
diff
changeset
|
273 |
(* FIXME proper name context!? *) |
42049 | 274 |
fun prep_pat ((c as Const (@{syntax_const "_constrain"}, _)) $ t $ tT) used = |
275 |
let val (t', used') = prep_pat t used |
|
276 |
in (c $ t' $ tT, used') end |
|
277 |
| prep_pat (Const (@{const_syntax dummy_pattern}, T)) used = |
|
43324
2b47822868e4
discontinued Name.variant to emphasize that this is old-style / indirect;
wenzelm
parents:
43257
diff
changeset
|
278 |
let val x = singleton (Name.variant_list used) "x" |
42049 | 279 |
in (Free (x, T), x :: used) end |
45700 | 280 |
| prep_pat (Const (s, T)) used = (Const (intern_const_syntax s, T), used) |
42049 | 281 |
| prep_pat (v as Free (s, T)) used = |
42361 | 282 |
let val s' = Proof_Context.intern_const ctxt s in |
45700 | 283 |
if Sign.declared_const thy s' then (Const (s', T), used) |
42049 | 284 |
else (v, used) |
285 |
end |
|
286 |
| prep_pat (t $ u) used = |
|
287 |
let |
|
288 |
val (t', used') = prep_pat t used; |
|
42359 | 289 |
val (u', used'') = prep_pat u used'; |
45700 | 290 |
in (t' $ u', used'') end |
42049 | 291 |
| prep_pat t used = case_error ("Bad pattern: " ^ Syntax.string_of_term ctxt t); |
45898 | 292 |
|
42049 | 293 |
fun dest_case1 (t as Const (@{syntax_const "_case1"}, _) $ l $ r) = |
294 |
let val (l', cnstrts) = strip_constraints l |
|
295 |
in ((fst (prep_pat l' (Term.add_free_names t [])), r), cnstrts) end |
|
296 |
| dest_case1 t = case_error "dest_case1"; |
|
45898 | 297 |
|
42049 | 298 |
fun dest_case2 (Const (@{syntax_const "_case2"}, _) $ t $ u) = t :: dest_case2 u |
299 |
| dest_case2 t = [t]; |
|
45898 | 300 |
|
42057
3eba96ff3d3e
more selective strip_positions in case patterns -- reactivate translations based on "case _ of _" in HOL and special patterns in HOLCF;
wenzelm
parents:
42050
diff
changeset
|
301 |
val (cases, cnstrts) = split_list (map dest_case1 (dest_case2 u)); |
45898 | 302 |
in |
303 |
make_case_untyped ctxt |
|
304 |
(if err then Error else Warning) [] |
|
305 |
(fold (fn tT => fn t => Syntax.const @{syntax_const "_constrain"} $ t $ tT) |
|
306 |
(flat cnstrts) t) cases |
|
307 |
end |
|
45894 | 308 |
| case_tr _ _ _ = case_error "case_tr"; |
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
309 |
|
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
310 |
val trfun_setup = |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
311 |
Sign.add_advanced_trfuns ([], |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
312 |
[(@{syntax_const "_case_syntax"}, case_tr true)], |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
313 |
[], []); |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
314 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
315 |
|
43255 | 316 |
(* Pretty printing of nested case expressions *) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
317 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
318 |
(* destruct one level of pattern matching *) |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
319 |
|
45889 | 320 |
local |
321 |
||
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
322 |
fun gen_dest_case name_of type_of ctxt d used t = |
42049 | 323 |
(case apfst name_of (strip_comb t) of |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
324 |
(SOME cname, ts as _ :: _) => |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
325 |
let |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
326 |
val (fs, x) = split_last ts; |
46059
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
327 |
fun strip_abs i Us t = |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
328 |
let |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
329 |
val zs = strip_abs_vars t; |
46059
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
330 |
val j = length zs; |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
331 |
val (xs, ys) = |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
332 |
if j < i then (zs @ map (pair "x") (drop j Us), []) |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
333 |
else chop i zs; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
334 |
val u = list_abs (ys, strip_abs_body t); |
46059
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
335 |
val xs' = map Free |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
336 |
((fold_map Name.variant (map fst xs) |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
337 |
(Term.declare_term_names u used) |> fst) ~~ |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
338 |
map snd xs); |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
339 |
val (xs1, xs2) = chop j xs' |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
340 |
in (xs', list_comb (subst_bounds (rev xs1, u), xs2)) end; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
341 |
fun is_dependent i t = |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
342 |
let val k = length (strip_abs_vars t) - i |
42049 | 343 |
in k < 0 orelse exists (fn j => j >= k) (loose_bnos (strip_abs_body t)) end; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
344 |
fun count_cases (_, _, true) = I |
45700 | 345 |
| count_cases (c, (_, body), false) = AList.map_default op aconv (body, []) (cons c); |
35392
5da5ac6c6b77
gen_dest_case: recovered @{const_name} from c8a6fae0ad0c, because of separate Syntax.mark_const in case_tr' -- avoid extra syntax markers in output;
wenzelm
parents:
35363
diff
changeset
|
346 |
val is_undefined = name_of #> equal (SOME @{const_name undefined}); |
45700 | 347 |
fun mk_case (c, (xs, body), _) = (list_comb (c, xs), body); |
45894 | 348 |
val get_info = Datatype_Data.info_of_case (Proof_Context.theory_of ctxt); |
42049 | 349 |
in |
45894 | 350 |
(case Option.map ty_info (get_info cname) of |
351 |
SOME {constructors, ...} => |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
352 |
if length fs = length constructors then |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
353 |
let |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
354 |
val cases = map (fn (Const (s, U), t) => |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
355 |
let |
46059
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
356 |
val Us = binder_types U; |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
357 |
val k = length Us; |
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
358 |
val p as (xs, _) = strip_abs k Us t; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
359 |
in |
45700 | 360 |
(Const (s, map type_of xs ---> type_of x), p, is_dependent k t) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
361 |
end) (constructors ~~ fs); |
45700 | 362 |
val cases' = |
363 |
sort (int_ord o swap o pairself (length o snd)) |
|
364 |
(fold_rev count_cases cases []); |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
365 |
val R = type_of t; |
35124 | 366 |
val dummy = |
45156 | 367 |
if d then Term.dummy_pattern R |
46059
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
368 |
else Free (Name.variant "x" used |> fst, R); |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
369 |
in |
42049 | 370 |
SOME (x, |
371 |
map mk_case |
|
372 |
(case find_first (is_undefined o fst) cases' of |
|
373 |
SOME (_, cs) => |
|
45700 | 374 |
if length cs = length constructors then [hd cases] |
375 |
else filter_out (fn (_, (_, body), _) => is_undefined body) cases |
|
376 |
| NONE => |
|
377 |
(case cases' of |
|
378 |
[] => cases |
|
379 |
| (default, cs) :: _ => |
|
380 |
if length cs = 1 then cases |
|
381 |
else if length cs = length constructors then |
|
382 |
[hd cases, (dummy, ([], default), false)] |
|
383 |
else |
|
384 |
filter_out (fn (c, _, _) => member op aconv cs c) cases @ |
|
385 |
[(dummy, ([], default), false)]))) |
|
46059
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
386 |
end |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
387 |
else NONE |
42049 | 388 |
| _ => NONE) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
389 |
end |
42049 | 390 |
| _ => NONE); |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
391 |
|
45889 | 392 |
in |
393 |
||
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
394 |
val dest_case = gen_dest_case (try (dest_Const #> fst)) fastype_of; |
42290
b1f544c84040
discontinued special treatment of structure Lexicon;
wenzelm
parents:
42284
diff
changeset
|
395 |
val dest_case' = gen_dest_case (try (dest_Const #> fst #> Lexicon.unmark_const)) (K dummyT); |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
396 |
|
45889 | 397 |
end; |
398 |
||
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
399 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
400 |
(* destruct nested patterns *) |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
401 |
|
45889 | 402 |
local |
403 |
||
29623 | 404 |
fun strip_case'' dest (pat, rhs) = |
46059
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
405 |
(case dest (Term.declare_term_frees pat Name.context) rhs of |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
406 |
SOME (exp as Free _, clauses) => |
45738 | 407 |
if Term.exists_subterm (curry (op aconv) exp) pat andalso |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
408 |
not (exists (fn (_, rhs') => |
45738 | 409 |
Term.exists_subterm (curry (op aconv) exp) rhs') clauses) |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
410 |
then |
29623 | 411 |
maps (strip_case'' dest) (map (fn (pat', rhs') => |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
412 |
(subst_free [(exp, pat')] pat, rhs')) clauses) |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
413 |
else [(pat, rhs)] |
42049 | 414 |
| _ => [(pat, rhs)]); |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
415 |
|
35124 | 416 |
fun gen_strip_case dest t = |
46059
f805747f8571
Made gen_dest_case more robust against eta contraction
berghofe
parents:
46003
diff
changeset
|
417 |
(case dest Name.context t of |
45700 | 418 |
SOME (x, clauses) => SOME (x, maps (strip_case'' dest) clauses) |
42049 | 419 |
| NONE => NONE); |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
420 |
|
45889 | 421 |
in |
422 |
||
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
423 |
val strip_case = gen_strip_case oo dest_case; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
424 |
val strip_case' = gen_strip_case oo dest_case'; |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
425 |
|
45889 | 426 |
end; |
427 |
||
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
428 |
|
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
429 |
(* print translation *) |
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
430 |
|
46003
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
431 |
val show_cases = Attrib.setup_config_bool @{binding show_cases} (K true); |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
432 |
|
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
433 |
fun case_tr' cname ctxt ts = |
46003
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
434 |
if Config.get ctxt show_cases then |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
435 |
let |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
436 |
fun mk_clause (pat, rhs) = |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
437 |
let val xs = Term.add_frees pat [] in |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
438 |
Syntax.const @{syntax_const "_case1"} $ |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
439 |
map_aterms |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
440 |
(fn Free p => Syntax_Trans.mark_boundT p |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
441 |
| Const (s, _) => Syntax.const (Lexicon.mark_const s) |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
442 |
| t => t) pat $ |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
443 |
map_aterms |
46125
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
444 |
(fn x as Free (s, T) => |
00cd193a48dc
improved case syntax: more careful treatment of position constraints, which enables PIDE markup;
wenzelm
parents:
46059
diff
changeset
|
445 |
if member (op =) xs (s, T) then Syntax_Trans.mark_bound s else x |
46003
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
446 |
| t => t) rhs |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
447 |
end; |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
448 |
in |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
449 |
(case strip_case' ctxt true (list_comb (Syntax.const cname, ts)) of |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
450 |
SOME (x, clauses) => |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
451 |
Syntax.const @{syntax_const "_case_syntax"} $ x $ |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
452 |
foldr1 (fn (t, u) => Syntax.const @{syntax_const "_case2"} $ t $ u) |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
453 |
(map mk_clause clauses) |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
454 |
| NONE => raise Match) |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
455 |
end |
c0fe5e8e4864
print case syntax depending on "show_cases" configuration option;
wenzelm
parents:
45898
diff
changeset
|
456 |
else raise Match; |
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
457 |
|
45891
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
458 |
fun add_case_tr' case_names thy = |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
459 |
Sign.add_advanced_trfuns ([], [], |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
460 |
map (fn case_name => |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
461 |
let val case_name' = Lexicon.mark_const case_name |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
462 |
in (case_name', case_tr' case_name') end) case_names, []) thy; |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
463 |
|
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
464 |
|
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
465 |
(* theory setup *) |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
466 |
|
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
467 |
val setup = trfun_setup; |
d73605c829cc
clarified module dependencies: Datatype_Data, Datatype_Case, Rep_Datatype;
wenzelm
parents:
45889
diff
changeset
|
468 |
|
22779
9ac0ca736969
Parse / print translations for nested case expressions, taken
berghofe
parents:
diff
changeset
|
469 |
end; |