155 fun mtype_of_mterm (MRaw (_, M)) = M |
161 fun mtype_of_mterm (MRaw (_, M)) = M |
156 | mtype_of_mterm (MAbs (_, _, M, a, m)) = MFun (M, a, mtype_of_mterm m) |
162 | mtype_of_mterm (MAbs (_, _, M, a, m)) = MFun (M, a, mtype_of_mterm m) |
157 | mtype_of_mterm (MApp (m1, _)) = |
163 | mtype_of_mterm (MApp (m1, _)) = |
158 case mtype_of_mterm m1 of |
164 case mtype_of_mterm m1 of |
159 MFun (_, _, M12) => M12 |
165 MFun (_, _, M12) => M12 |
160 | M1 => raise MTYPE ("Nitpick_Mono.mtype_of_mterm", [M1]) |
166 | M1 => raise MTYPE ("Nitpick_Mono.mtype_of_mterm", [M1], []) |
161 |
167 |
162 (* hol_context -> bool -> typ -> mdata *) |
168 (* mterm -> mterm * mterm list *) |
163 fun initial_mdata hol_ctxt binarize alpha_T = |
169 fun strip_mcomb (MApp (m1, m2)) = strip_mcomb m1 ||> (fn ms => append ms [m2]) |
|
170 | strip_mcomb m = (m, []) |
|
171 |
|
172 (* hol_context -> bool -> bool -> typ -> mdata *) |
|
173 fun initial_mdata hol_ctxt binarize no_harmless alpha_T = |
164 ({hol_ctxt = hol_ctxt, binarize = binarize, alpha_T = alpha_T, |
174 ({hol_ctxt = hol_ctxt, binarize = binarize, alpha_T = alpha_T, |
165 max_fresh = Unsynchronized.ref 0, datatype_cache = Unsynchronized.ref [], |
175 no_harmless = no_harmless, max_fresh = Unsynchronized.ref 0, |
166 constr_cache = Unsynchronized.ref []} : mdata) |
176 datatype_mcache = Unsynchronized.ref [], |
|
177 constr_mcache = Unsynchronized.ref []} : mdata) |
167 |
178 |
168 (* typ -> typ -> bool *) |
179 (* typ -> typ -> bool *) |
169 fun could_exist_alpha_subtype alpha_T (T as Type (_, Ts)) = |
180 fun could_exist_alpha_subtype alpha_T (T as Type (_, Ts)) = |
170 T = alpha_T orelse (not (is_fp_iterator_type T) andalso |
181 T = alpha_T orelse (not (is_fp_iterator_type T) andalso |
171 exists (could_exist_alpha_subtype alpha_T) Ts) |
182 exists (could_exist_alpha_subtype alpha_T) Ts) |
213 MRec _ => MType (s, []) |
224 MRec _ => MType (s, []) |
214 | M => if member (op =) seen M then MType (s, []) |
225 | M => if member (op =) seen M then MType (s, []) |
215 else repair_mtype cache (M :: seen) M |
226 else repair_mtype cache (M :: seen) M |
216 |
227 |
217 (* ((string * typ list) * mtyp) list Unsynchronized.ref -> unit *) |
228 (* ((string * typ list) * mtyp) list Unsynchronized.ref -> unit *) |
218 fun repair_datatype_cache cache = |
229 fun repair_datatype_mcache cache = |
219 let |
230 let |
220 (* (string * typ list) * mtyp -> unit *) |
231 (* (string * typ list) * mtyp -> unit *) |
221 fun repair_one (z, M) = |
232 fun repair_one (z, M) = |
222 Unsynchronized.change cache |
233 Unsynchronized.change cache |
223 (AList.update (op =) (z, repair_mtype (!cache) [] M)) |
234 (AList.update (op =) (z, repair_mtype (!cache) [] M)) |
224 in List.app repair_one (rev (!cache)) end |
235 in List.app repair_one (rev (!cache)) end |
225 |
236 |
226 (* (typ * mtyp) list -> (styp * mtyp) list Unsynchronized.ref -> unit *) |
237 (* (typ * mtyp) list -> (styp * mtyp) list Unsynchronized.ref -> unit *) |
227 fun repair_constr_cache dtype_cache constr_cache = |
238 fun repair_constr_mcache dtype_cache constr_mcache = |
228 let |
239 let |
229 (* styp * mtyp -> unit *) |
240 (* styp * mtyp -> unit *) |
230 fun repair_one (x, M) = |
241 fun repair_one (x, M) = |
231 Unsynchronized.change constr_cache |
242 Unsynchronized.change constr_mcache |
232 (AList.update (op =) (x, repair_mtype dtype_cache [] M)) |
243 (AList.update (op =) (x, repair_mtype dtype_cache [] M)) |
233 in List.app repair_one (!constr_cache) end |
244 in List.app repair_one (!constr_mcache) end |
|
245 |
|
246 (* typ -> bool *) |
|
247 fun is_fin_fun_supported_type @{typ prop} = true |
|
248 | is_fin_fun_supported_type @{typ bool} = true |
|
249 | is_fin_fun_supported_type (Type (@{type_name option}, _)) = true |
|
250 | is_fin_fun_supported_type _ = false |
|
251 (* typ -> typ -> term -> term option *) |
|
252 fun fin_fun_body _ _ (t as @{term False}) = SOME t |
|
253 | fin_fun_body _ _ (t as Const (@{const_name None}, _)) = SOME t |
|
254 | fin_fun_body dom_T ran_T |
|
255 ((t0 as Const (@{const_name If}, _)) |
|
256 $ (t1 as Const (@{const_name "op ="}, _) $ Bound 0 $ t1') |
|
257 $ t2 $ t3) = |
|
258 (if loose_bvar1 (t1', 0) then |
|
259 NONE |
|
260 else case fin_fun_body dom_T ran_T t3 of |
|
261 NONE => NONE |
|
262 | SOME t3 => |
|
263 SOME (t0 $ (Const (@{const_name is_unknown}, dom_T --> bool_T) $ t1') |
|
264 $ (Const (@{const_name unknown}, ran_T)) $ (t0 $ t1 $ t2 $ t3))) |
|
265 | fin_fun_body _ _ _ = NONE |
234 |
266 |
235 (* mdata -> typ -> typ -> mtyp * sign_atom * mtyp *) |
267 (* mdata -> typ -> typ -> mtyp * sign_atom * mtyp *) |
236 fun fresh_mfun_for_fun_type (mdata as {max_fresh, ...} : mdata) T1 T2 = |
268 fun fresh_mfun_for_fun_type (mdata as {max_fresh, ...} : mdata) T1 T2 = |
237 let |
269 let |
238 val M1 = fresh_mtype_for_type mdata T1 |
270 val M1 = fresh_mtype_for_type mdata T1 |
239 val M2 = fresh_mtype_for_type mdata T2 |
271 val M2 = fresh_mtype_for_type mdata T2 |
240 val a = if is_boolean_type (body_type T2) andalso |
272 val a = if is_fin_fun_supported_type (body_type T2) andalso |
241 exists_alpha_sub_mtype_fresh M1 then |
273 exists_alpha_sub_mtype_fresh M1 then |
242 V (Unsynchronized.inc max_fresh) |
274 V (Unsynchronized.inc max_fresh) |
243 else |
275 else |
244 S Minus |
276 S Minus |
245 in (M1, a, M2) end |
277 in (M1, a, M2) end |
246 (* mdata -> typ -> mtyp *) |
278 (* mdata -> typ -> mtyp *) |
247 and fresh_mtype_for_type (mdata as {hol_ctxt as {thy, ...}, binarize, alpha_T, |
279 and fresh_mtype_for_type (mdata as {hol_ctxt as {thy, ...}, binarize, alpha_T, |
248 datatype_cache, constr_cache, ...}) = |
280 datatype_mcache, constr_mcache, ...}) = |
249 let |
281 let |
250 (* typ -> typ -> mtyp *) |
|
251 val do_fun = MFun oo fresh_mfun_for_fun_type mdata |
|
252 (* typ -> mtyp *) |
282 (* typ -> mtyp *) |
253 fun do_type T = |
283 fun do_type T = |
254 if T = alpha_T then |
284 if T = alpha_T then |
255 MAlpha |
285 MAlpha |
256 else case T of |
286 else case T of |
257 Type ("fun", [T1, T2]) => do_fun T1 T2 |
287 Type (@{type_name fun}, [T1, T2]) => |
258 | Type (@{type_name fun_box}, [T1, T2]) => do_fun T1 T2 |
288 MFun (fresh_mfun_for_fun_type mdata T1 T2) |
259 | Type ("*", [T1, T2]) => MPair (pairself do_type (T1, T2)) |
289 | Type (@{type_name "*"}, [T1, T2]) => MPair (pairself do_type (T1, T2)) |
260 | Type (z as (s, _)) => |
290 | Type (z as (s, _)) => |
261 if could_exist_alpha_sub_mtype thy alpha_T T then |
291 if could_exist_alpha_sub_mtype thy alpha_T T then |
262 case AList.lookup (op =) (!datatype_cache) z of |
292 case AList.lookup (op =) (!datatype_mcache) z of |
263 SOME M => M |
293 SOME M => M |
264 | NONE => |
294 | NONE => |
265 let |
295 let |
266 val _ = Unsynchronized.change datatype_cache (cons (z, MRec z)) |
296 val _ = Unsynchronized.change datatype_mcache (cons (z, MRec z)) |
267 val xs = binarized_and_boxed_datatype_constrs hol_ctxt binarize T |
297 val xs = binarized_and_boxed_datatype_constrs hol_ctxt binarize T |
268 val (all_Ms, constr_Ms) = |
298 val (all_Ms, constr_Ms) = |
269 fold_rev (fn (_, T') => fn (all_Ms, constr_Ms) => |
299 fold_rev (fn (_, T') => fn (all_Ms, constr_Ms) => |
270 let |
300 let |
271 val binder_Ms = map do_type (binder_types T') |
301 val binder_Ms = map do_type (binder_types T') |
298 |
328 |
299 (* mtyp -> mtyp list *) |
329 (* mtyp -> mtyp list *) |
300 fun prodM_factors (MPair (M1, M2)) = maps prodM_factors [M1, M2] |
330 fun prodM_factors (MPair (M1, M2)) = maps prodM_factors [M1, M2] |
301 | prodM_factors M = [M] |
331 | prodM_factors M = [M] |
302 (* mtyp -> mtyp list * mtyp *) |
332 (* mtyp -> mtyp list * mtyp *) |
303 fun curried_strip_mtype (MFun (M1, S Minus, M2)) = |
333 fun curried_strip_mtype (MFun (M1, _, M2)) = |
304 curried_strip_mtype M2 |>> append (prodM_factors M1) |
334 curried_strip_mtype M2 |>> append (prodM_factors M1) |
305 | curried_strip_mtype M = ([], M) |
335 | curried_strip_mtype M = ([], M) |
306 (* string -> mtyp -> mtyp *) |
336 (* string -> mtyp -> mtyp *) |
307 fun sel_mtype_from_constr_mtype s M = |
337 fun sel_mtype_from_constr_mtype s M = |
308 let val (arg_Ms, dataM) = curried_strip_mtype M in |
338 let val (arg_Ms, dataM) = curried_strip_mtype M in |
309 MFun (dataM, S Minus, |
339 MFun (dataM, S Minus, |
310 case sel_no_from_name s of ~1 => bool_M | n => nth arg_Ms n) |
340 case sel_no_from_name s of ~1 => bool_M | n => nth arg_Ms n) |
311 end |
341 end |
312 |
342 |
313 (* mdata -> styp -> mtyp *) |
343 (* mdata -> styp -> mtyp *) |
314 fun mtype_for_constr (mdata as {hol_ctxt = {thy, ...}, alpha_T, constr_cache, |
344 fun mtype_for_constr (mdata as {hol_ctxt = {thy, ...}, alpha_T, constr_mcache, |
315 ...}) (x as (_, T)) = |
345 ...}) (x as (_, T)) = |
316 if could_exist_alpha_sub_mtype thy alpha_T T then |
346 if could_exist_alpha_sub_mtype thy alpha_T T then |
317 case AList.lookup (op =) (!constr_cache) x of |
347 case AList.lookup (op =) (!constr_mcache) x of |
318 SOME M => M |
348 SOME M => M |
319 | NONE => if T = alpha_T then |
349 | NONE => if T = alpha_T then |
320 let val M = fresh_mtype_for_type mdata T in |
350 let val M = fresh_mtype_for_type mdata T in |
321 (Unsynchronized.change constr_cache (cons (x, M)); M) |
351 (Unsynchronized.change constr_mcache (cons (x, M)); M) |
322 end |
352 end |
323 else |
353 else |
324 (fresh_mtype_for_type mdata (body_type T); |
354 (fresh_mtype_for_type mdata (body_type T); |
325 AList.lookup (op =) (!constr_cache) x |> the) |
355 AList.lookup (op =) (!constr_mcache) x |> the) |
326 else |
356 else |
327 fresh_mtype_for_type mdata T |
357 fresh_mtype_for_type mdata T |
328 fun mtype_for_sel (mdata as {hol_ctxt, binarize, ...}) (x as (s, _)) = |
358 fun mtype_for_sel (mdata as {hol_ctxt, binarize, ...}) (x as (s, _)) = |
329 x |> binarized_and_boxed_constr_for_sel hol_ctxt binarize |
359 x |> binarized_and_boxed_constr_for_sel hol_ctxt binarize |
330 |> mtype_for_constr mdata |> sel_mtype_from_constr_mtype s |
360 |> mtype_for_constr mdata |> sel_mtype_from_constr_mtype s |
331 |
361 |
|
362 (* literal list -> sign_atom -> sign_atom *) |
|
363 fun resolve_sign_atom lits (V x) = |
|
364 x |> AList.lookup (op =) lits |> Option.map S |> the_default (V x) |
|
365 | resolve_sign_atom _ a = a |
332 (* literal list -> mtyp -> mtyp *) |
366 (* literal list -> mtyp -> mtyp *) |
333 fun instantiate_mtype lits = |
367 fun resolve_mtype lits = |
334 let |
368 let |
335 (* mtyp -> mtyp *) |
369 (* mtyp -> mtyp *) |
336 fun aux MAlpha = MAlpha |
370 fun aux MAlpha = MAlpha |
337 | aux (MFun (M1, V x, M2)) = |
371 | aux (MFun (M1, a, M2)) = MFun (aux M1, resolve_sign_atom lits a, aux M2) |
338 let |
|
339 val a = case AList.lookup (op =) lits x of |
|
340 SOME sn => S sn |
|
341 | NONE => V x |
|
342 in MFun (aux M1, a, aux M2) end |
|
343 | aux (MFun (M1, a, M2)) = MFun (aux M1, a, aux M2) |
|
344 | aux (MPair Mp) = MPair (pairself aux Mp) |
372 | aux (MPair Mp) = MPair (pairself aux Mp) |
345 | aux (MType (s, Ms)) = MType (s, map aux Ms) |
373 | aux (MType (s, Ms)) = MType (s, map aux Ms) |
346 | aux (MRec z) = MRec z |
374 | aux (MRec z) = MRec z |
347 in aux end |
375 in aux end |
348 |
376 |
469 | do_notin_mtype_fv sn sexp (MPair (M1, M2)) accum = |
498 | do_notin_mtype_fv sn sexp (MPair (M1, M2)) accum = |
470 accum |> fold (do_notin_mtype_fv sn sexp) [M1, M2] |
499 accum |> fold (do_notin_mtype_fv sn sexp) [M1, M2] |
471 | do_notin_mtype_fv sn sexp (MType (_, Ms)) accum = |
500 | do_notin_mtype_fv sn sexp (MType (_, Ms)) accum = |
472 accum |> fold (do_notin_mtype_fv sn sexp) Ms |
501 accum |> fold (do_notin_mtype_fv sn sexp) Ms |
473 | do_notin_mtype_fv _ _ M _ = |
502 | do_notin_mtype_fv _ _ M _ = |
474 raise MTYPE ("Nitpick_Mono.do_notin_mtype_fv", [M]) |
503 raise MTYPE ("Nitpick_Mono.do_notin_mtype_fv", [M], []) |
475 |
504 |
476 (* sign -> mtyp -> constraint_set -> constraint_set *) |
505 (* sign -> mtyp -> constraint_set -> constraint_set *) |
477 fun add_notin_mtype_fv _ _ UnsolvableCSet = UnsolvableCSet |
506 fun add_notin_mtype_fv _ _ UnsolvableCSet = UnsolvableCSet |
478 | add_notin_mtype_fv sn M (CSet (lits, comps, sexps)) = |
507 | add_notin_mtype_fv sn M (CSet (lits, comps, sexps)) = |
479 (print_g ("*** Add " ^ string_for_mtype M ^ " is right-" ^ |
508 (print_g ("*** Add " ^ string_for_mtype M ^ " is " ^ |
480 (case sn of Minus => "unique" | Plus => "total") ^ "."); |
509 (case sn of Minus => "concrete" | Plus => "complete") ^ "."); |
481 case do_notin_mtype_fv sn [] M (SOME (lits, sexps)) of |
510 case do_notin_mtype_fv sn [] M (SOME (lits, sexps)) of |
482 NONE => (print_g "**** Unsolvable"; UnsolvableCSet) |
511 NONE => (print_g "**** Unsolvable"; UnsolvableCSet) |
483 | SOME (lits, sexps) => CSet (lits, comps, sexps)) |
512 | SOME (lits, sexps) => CSet (lits, comps, sexps)) |
484 |
513 |
485 (* mtyp -> constraint_set -> constraint_set *) |
514 (* mtyp -> constraint_set -> constraint_set *) |
486 val add_mtype_is_right_unique = add_notin_mtype_fv Minus |
515 val add_mtype_is_concrete = add_notin_mtype_fv Minus |
487 val add_mtype_is_right_total = add_notin_mtype_fv Plus |
516 val add_mtype_is_complete = add_notin_mtype_fv Plus |
488 |
517 |
489 val bool_from_minus = true |
518 val bool_from_minus = true |
490 |
519 |
491 (* sign -> bool *) |
520 (* sign -> bool *) |
492 fun bool_from_sign Plus = not bool_from_minus |
521 fun bool_from_sign Plus = not bool_from_minus |
572 end |
601 end |
573 end |
602 end |
574 |
603 |
575 type mtype_schema = mtyp * constraint_set |
604 type mtype_schema = mtyp * constraint_set |
576 type mtype_context = |
605 type mtype_context = |
577 {bounds: mtyp list, |
606 {bound_Ts: typ list, |
|
607 bound_Ms: mtyp list, |
578 frees: (styp * mtyp) list, |
608 frees: (styp * mtyp) list, |
579 consts: (styp * mtyp) list} |
609 consts: (styp * mtyp) list} |
580 |
610 |
581 type accumulator = mtype_context * constraint_set |
611 type accumulator = mtype_context * constraint_set |
582 |
612 |
583 val initial_gamma = {bounds = [], frees = [], consts = []} |
613 val initial_gamma = {bound_Ts = [], bound_Ms = [], frees = [], consts = []} |
584 val unsolvable_accum = (initial_gamma, UnsolvableCSet) |
614 val unsolvable_accum = (initial_gamma, UnsolvableCSet) |
585 |
615 |
586 (* mtyp -> mtype_context -> mtype_context *) |
616 (* typ -> mtyp -> mtype_context -> mtype_context *) |
587 fun push_bound M {bounds, frees, consts} = |
617 fun push_bound T M {bound_Ts, bound_Ms, frees, consts} = |
588 {bounds = M :: bounds, frees = frees, consts = consts} |
618 {bound_Ts = T :: bound_Ts, bound_Ms = M :: bound_Ms, frees = frees, |
|
619 consts = consts} |
589 (* mtype_context -> mtype_context *) |
620 (* mtype_context -> mtype_context *) |
590 fun pop_bound {bounds, frees, consts} = |
621 fun pop_bound {bound_Ts, bound_Ms, frees, consts} = |
591 {bounds = tl bounds, frees = frees, consts = consts} |
622 {bound_Ts = tl bound_Ts, bound_Ms = tl bound_Ms, frees = frees, |
592 handle List.Empty => initial_gamma |
623 consts = consts} |
|
624 handle List.Empty => initial_gamma (* FIXME: needed? *) |
593 |
625 |
594 (* mdata -> term -> accumulator -> mterm * accumulator *) |
626 (* mdata -> term -> accumulator -> mterm * accumulator *) |
595 fun consider_term (mdata as {hol_ctxt as {thy, ctxt, stds, fast_descrs, |
627 fun consider_term (mdata as {hol_ctxt as {thy, ctxt, stds, fast_descrs, |
596 def_table, ...}, |
628 def_table, ...}, |
597 alpha_T, max_fresh, ...}) = |
629 alpha_T, max_fresh, ...}) = |
598 let |
630 let |
599 (* typ -> typ -> mtyp * sign_atom * mtyp *) |
|
600 val mfun_for = fresh_mfun_for_fun_type mdata |
|
601 (* typ -> mtyp *) |
631 (* typ -> mtyp *) |
602 val mtype_for = fresh_mtype_for_type mdata |
632 val mtype_for = fresh_mtype_for_type mdata |
603 (* mtyp -> mtyp *) |
633 (* mtyp -> mtyp *) |
604 fun pos_set_mtype_for_dom M = |
634 fun plus_set_mtype_for_dom M = |
605 MFun (M, S (if exists_alpha_sub_mtype M then Plus else Minus), bool_M) |
635 MFun (M, S (if exists_alpha_sub_mtype M then Plus else Minus), bool_M) |
606 (* typ -> accumulator -> mterm * accumulator *) |
636 (* typ -> accumulator -> mterm * accumulator *) |
607 fun do_all T (gamma, cset) = |
637 fun do_all T (gamma, cset) = |
608 let |
638 let |
609 val abs_M = mtype_for (domain_type (domain_type T)) |
639 val abs_M = mtype_for (domain_type (domain_type T)) |
610 val body_M = mtype_for (body_type T) |
640 val body_M = mtype_for (body_type T) |
611 in |
641 in |
612 (MFun (MFun (abs_M, S Minus, body_M), S Minus, body_M), |
642 (MFun (MFun (abs_M, S Minus, body_M), S Minus, body_M), |
613 (gamma, cset |> add_mtype_is_right_total abs_M)) |
643 (gamma, cset |> add_mtype_is_complete abs_M)) |
614 end |
644 end |
615 fun do_equals T (gamma, cset) = |
645 fun do_equals T (gamma, cset) = |
616 let val M = mtype_for (domain_type T) in |
646 let val M = mtype_for (domain_type T) in |
617 (MFun (M, S Minus, MFun (M, V (Unsynchronized.inc max_fresh), |
647 (MFun (M, S Minus, MFun (M, V (Unsynchronized.inc max_fresh), |
618 mtype_for (nth_range_type 2 T))), |
648 mtype_for (nth_range_type 2 T))), |
619 (gamma, cset |> add_mtype_is_right_unique M)) |
649 (gamma, cset |> add_mtype_is_concrete M)) |
620 end |
650 end |
621 fun do_robust_set_operation T (gamma, cset) = |
651 fun do_robust_set_operation T (gamma, cset) = |
622 let |
652 let |
623 val set_T = domain_type T |
653 val set_T = domain_type T |
624 val M1 = mtype_for set_T |
654 val M1 = mtype_for set_T |
631 fun do_fragile_set_operation T (gamma, cset) = |
661 fun do_fragile_set_operation T (gamma, cset) = |
632 let |
662 let |
633 val set_T = domain_type T |
663 val set_T = domain_type T |
634 val set_M = mtype_for set_T |
664 val set_M = mtype_for set_T |
635 (* typ -> mtyp *) |
665 (* typ -> mtyp *) |
636 fun custom_mtype_for (T as Type ("fun", [T1, T2])) = |
666 fun custom_mtype_for (T as Type (@{type_name fun}, [T1, T2])) = |
637 if T = set_T then set_M |
667 if T = set_T then set_M |
638 else MFun (custom_mtype_for T1, S Minus, custom_mtype_for T2) |
668 else MFun (custom_mtype_for T1, S Minus, custom_mtype_for T2) |
639 | custom_mtype_for T = mtype_for T |
669 | custom_mtype_for T = mtype_for T |
640 in |
670 in |
641 (custom_mtype_for T, (gamma, cset |> add_mtype_is_right_unique set_M)) |
671 (custom_mtype_for T, (gamma, cset |> add_mtype_is_concrete set_M)) |
642 end |
672 end |
643 (* typ -> accumulator -> mtyp * accumulator *) |
673 (* typ -> accumulator -> mtyp * accumulator *) |
644 fun do_pair_constr T accum = |
674 fun do_pair_constr T accum = |
645 case mtype_for (nth_range_type 2 T) of |
675 case mtype_for (nth_range_type 2 T) of |
646 M as MPair (a_M, b_M) => |
676 M as MPair (a_M, b_M) => |
647 (MFun (a_M, S Minus, MFun (b_M, S Minus, M)), accum) |
677 (MFun (a_M, S Minus, MFun (b_M, S Minus, M)), accum) |
648 | M => raise MTYPE ("Nitpick_Mono.consider_term.do_pair_constr", [M]) |
678 | M => raise MTYPE ("Nitpick_Mono.consider_term.do_pair_constr", [M], []) |
649 (* int -> typ -> accumulator -> mtyp * accumulator *) |
679 (* int -> typ -> accumulator -> mtyp * accumulator *) |
650 fun do_nth_pair_sel n T = |
680 fun do_nth_pair_sel n T = |
651 case mtype_for (domain_type T) of |
681 case mtype_for (domain_type T) of |
652 M as MPair (a_M, b_M) => |
682 M as MPair (a_M, b_M) => |
653 pair (MFun (M, S Minus, if n = 0 then a_M else b_M)) |
683 pair (MFun (M, S Minus, if n = 0 then a_M else b_M)) |
654 | M => raise MTYPE ("Nitpick_Mono.consider_term.do_nth_pair_sel", [M]) |
684 | M => raise MTYPE ("Nitpick_Mono.consider_term.do_nth_pair_sel", [M], []) |
655 (* mtyp * accumulator *) |
685 (* mtyp * accumulator *) |
656 val mtype_unsolvable = (dummy_M, unsolvable_accum) |
686 val mtype_unsolvable = (dummy_M, unsolvable_accum) |
657 (* term -> mterm * accumulator *) |
687 (* term -> mterm * accumulator *) |
658 fun mterm_unsolvable t = (MRaw (t, dummy_M), unsolvable_accum) |
688 fun mterm_unsolvable t = (MRaw (t, dummy_M), unsolvable_accum) |
659 (* term -> string -> typ -> term -> term -> term -> accumulator |
689 (* term -> string -> typ -> term -> term -> term -> accumulator |
660 -> mterm * accumulator *) |
690 -> mterm * accumulator *) |
661 fun do_bounded_quantifier t0 abs_s abs_T connective_t bound_t body_t accum = |
691 fun do_bounded_quantifier t0 abs_s abs_T connective_t bound_t body_t accum = |
662 let |
692 let |
663 val abs_M = mtype_for abs_T |
693 val abs_M = mtype_for abs_T |
664 val (bound_m, accum) = accum |>> push_bound abs_M |> do_term bound_t |
694 val (bound_m, accum) = |
665 val expected_bound_M = pos_set_mtype_for_dom abs_M |
695 accum |>> push_bound abs_T abs_M |> do_term bound_t |
|
696 val expected_bound_M = plus_set_mtype_for_dom abs_M |
666 val (body_m, accum) = |
697 val (body_m, accum) = |
667 accum ||> add_mtypes_equal expected_bound_M (mtype_of_mterm bound_m) |
698 accum ||> add_mtypes_equal expected_bound_M (mtype_of_mterm bound_m) |
668 |> do_term body_t ||> apfst pop_bound |
699 |> do_term body_t ||> apfst pop_bound |
669 val bound_M = mtype_of_mterm bound_m |
700 val bound_M = mtype_of_mterm bound_m |
670 val (M1, a, M2) = dest_MFun bound_M |
701 val (M1, a, M2) = dest_MFun bound_M |
782 MFun (a_to_b_set_M, S Minus, ab_set_M)), accum) |
814 MFun (a_to_b_set_M, S Minus, ab_set_M)), accum) |
783 end |
815 end |
784 | @{const_name Tha} => |
816 | @{const_name Tha} => |
785 let |
817 let |
786 val a_M = mtype_for (domain_type (domain_type T)) |
818 val a_M = mtype_for (domain_type (domain_type T)) |
787 val a_set_M = pos_set_mtype_for_dom a_M |
819 val a_set_M = plus_set_mtype_for_dom a_M |
788 in (MFun (a_set_M, S Minus, a_M), accum) end |
820 in (MFun (a_set_M, S Minus, a_M), accum) end |
789 | @{const_name FunBox} => |
|
790 let val dom_M = mtype_for (domain_type T) in |
|
791 (MFun (dom_M, S Minus, dom_M), accum) |
|
792 end |
|
793 | _ => |
821 | _ => |
794 if s = @{const_name minus_class.minus} andalso |
822 if s = @{const_name minus_class.minus} andalso |
795 is_set_type (domain_type T) then |
823 is_set_type (domain_type T) then |
796 let |
824 let |
797 val set_T = domain_type T |
825 val set_T = domain_type T |
798 val left_set_M = mtype_for set_T |
826 val left_set_M = mtype_for set_T |
799 val right_set_M = mtype_for set_T |
827 val right_set_M = mtype_for set_T |
800 in |
828 in |
801 (MFun (left_set_M, S Minus, |
829 (MFun (left_set_M, S Minus, |
802 MFun (right_set_M, S Minus, left_set_M)), |
830 MFun (right_set_M, S Minus, left_set_M)), |
803 (gamma, cset |> add_mtype_is_right_unique right_set_M |
831 (gamma, cset |> add_mtype_is_concrete right_set_M |
804 |> add_is_sub_mtype right_set_M left_set_M)) |
832 |> add_is_sub_mtype right_set_M left_set_M)) |
805 end |
833 end |
806 else if s = @{const_name ord_class.less_eq} andalso |
834 else if s = @{const_name ord_class.less_eq} andalso |
807 is_set_type (domain_type T) then |
835 is_set_type (domain_type T) then |
808 do_fragile_set_operation T accum |
836 do_fragile_set_operation T accum |
809 else if (s = @{const_name semilattice_inf_class.inf} orelse |
837 else if (s = @{const_name semilattice_inf_class.inf} orelse |
810 s = @{const_name semilattice_sup_class.sup}) andalso |
838 s = @{const_name semilattice_sup_class.sup}) andalso |
811 is_set_type (domain_type T) then |
839 is_set_type (domain_type T) then |
812 do_robust_set_operation T accum |
840 do_robust_set_operation T accum |
813 else if is_sel s then |
841 else if is_sel s then |
814 if constr_name_for_sel_like s = @{const_name FunBox} then |
842 (mtype_for_sel mdata x, accum) |
815 let val dom_M = mtype_for (domain_type T) in |
|
816 (MFun (dom_M, S Minus, dom_M), accum) |
|
817 end |
|
818 else |
|
819 (mtype_for_sel mdata x, accum) |
|
820 else if is_constr thy stds x then |
843 else if is_constr thy stds x then |
821 (mtype_for_constr mdata x, accum) |
844 (mtype_for_constr mdata x, accum) |
822 else if is_built_in_const thy stds fast_descrs x then |
845 else if is_built_in_const thy stds fast_descrs x andalso |
|
846 s <> @{const_name is_unknown} andalso |
|
847 s <> @{const_name unknown} then |
|
848 (* the "unknown" part is a hack *) |
823 case def_of_const thy def_table x of |
849 case def_of_const thy def_table x of |
824 SOME t' => do_term t' accum |>> mtype_of_mterm |
850 SOME t' => do_term t' accum |>> mtype_of_mterm |
825 | NONE => (print_g ("*** built-in " ^ s); mtype_unsolvable) |
851 | NONE => (print_g ("*** built-in " ^ s); mtype_unsolvable) |
826 else |
852 else |
827 let val M = mtype_for T in |
853 let val M = mtype_for T in |
828 (M, ({bounds = bounds, frees = frees, |
854 (M, ({bound_Ts = bound_Ts, bound_Ms = bound_Ms, |
829 consts = (x, M) :: consts}, cset)) |
855 frees = frees, consts = (x, M) :: consts}, cset)) |
830 end) |>> curry MRaw t |
856 end) |>> curry MRaw t |
831 | Free (x as (_, T)) => |
857 | Free (x as (_, T)) => |
832 (case AList.lookup (op =) frees x of |
858 (case AList.lookup (op =) frees x of |
833 SOME M => (M, accum) |
859 SOME M => (M, accum) |
834 | NONE => |
860 | NONE => |
835 let val M = mtype_for T in |
861 let val M = mtype_for T in |
836 (M, ({bounds = bounds, frees = (x, M) :: frees, |
862 (M, ({bound_Ts = bound_Ts, bound_Ms = bound_Ms, |
837 consts = consts}, cset)) |
863 frees = (x, M) :: frees, consts = consts}, cset)) |
838 end) |>> curry MRaw t |
864 end) |>> curry MRaw t |
839 | Var _ => (print_g "*** Var"; mterm_unsolvable t) |
865 | Var _ => (print_g "*** Var"; mterm_unsolvable t) |
840 | Bound j => (MRaw (t, nth bounds j), accum) |
866 | Bound j => (MRaw (t, nth bound_Ms j), accum) |
841 | Abs (s, T, t' as @{const False}) => |
|
842 let val (M1, a, M2) = mfun_for T bool_T in |
|
843 (MAbs (s, T, M1, a, MRaw (t', M2)), accum) |
|
844 end |
|
845 | Abs (s, T, t') => |
867 | Abs (s, T, t') => |
846 ((case t' of |
868 (case fin_fun_body T (fastype_of1 (T :: bound_Ts, t')) t' of |
847 t1' $ Bound 0 => |
869 SOME t' => |
848 if not (loose_bvar1 (t1', 0)) then |
870 let |
849 do_term (incr_boundvars ~1 t1') accum |
871 val M = mtype_for T |
850 else |
872 val a = V (Unsynchronized.inc max_fresh) |
851 raise SAME () |
873 val (m', accum) = do_term t' (accum |>> push_bound T M) |
852 | _ => raise SAME ()) |
874 in (MAbs (s, T, M, a, m'), accum |>> pop_bound) end |
853 handle SAME () => |
875 | NONE => |
854 let |
876 ((case t' of |
855 val M = mtype_for T |
877 t1' $ Bound 0 => |
856 val (m', accum) = do_term t' (accum |>> push_bound M) |
878 if not (loose_bvar1 (t1', 0)) then |
857 in (MAbs (s, T, M, S Minus, m'), accum |>> pop_bound) end) |
879 do_term (incr_boundvars ~1 t1') accum |
|
880 else |
|
881 raise SAME () |
|
882 | _ => raise SAME ()) |
|
883 handle SAME () => |
|
884 let |
|
885 val M = mtype_for T |
|
886 val (m', accum) = do_term t' (accum |>> push_bound T M) |
|
887 in |
|
888 (MAbs (s, T, M, S Minus, m'), accum |>> pop_bound) |
|
889 end)) |
858 | (t0 as Const (@{const_name All}, _)) |
890 | (t0 as Const (@{const_name All}, _)) |
859 $ Abs (s', T', (t10 as @{const "op -->"}) $ (t11 $ Bound 0) $ t12) => |
891 $ Abs (s', T', (t10 as @{const "op -->"}) $ (t11 $ Bound 0) $ t12) => |
860 do_bounded_quantifier t0 s' T' t10 t11 t12 accum |
892 do_bounded_quantifier t0 s' T' t10 t11 t12 accum |
861 | (t0 as Const (@{const_name Ex}, _)) |
893 | (t0 as Const (@{const_name Ex}, _)) |
862 $ Abs (s', T', (t10 as @{const "op &"}) $ (t11 $ Bound 0) $ t12) => |
894 $ Abs (s', T', (t10 as @{const "op &"}) $ (t11 $ Bound 0) $ t12) => |
870 in |
902 in |
871 case accum of |
903 case accum of |
872 (_, UnsolvableCSet) => mterm_unsolvable t |
904 (_, UnsolvableCSet) => mterm_unsolvable t |
873 | _ => |
905 | _ => |
874 let |
906 let |
|
907 val T11 = domain_type (fastype_of1 (bound_Ts, t1)) |
|
908 val T2 = fastype_of1 (bound_Ts, t2) |
875 val M11 = mtype_of_mterm m1 |> dest_MFun |> #1 |
909 val M11 = mtype_of_mterm m1 |> dest_MFun |> #1 |
876 val M2 = mtype_of_mterm m2 |
910 val M2 = mtype_of_mterm m2 |
877 in (MApp (m1, m2), accum ||> add_is_sub_mtype M2 M11) end |
911 in (MApp (m1, m2), accum ||> add_is_sub_mtype M2 M11) end |
878 end) |
912 end) |
879 |> tap (fn (m, _) => print_g (" \<Gamma> \<turnstile> " ^ |
913 |> tap (fn (m, _) => print_g (" \<Gamma> \<turnstile> " ^ |
880 string_for_mterm ctxt m)) |
914 string_for_mterm ctxt m)) |
881 in do_term end |
915 in do_term end |
882 |
916 |
883 (* mdata -> styp -> term -> term -> mterm * accumulator *) |
917 (* |
884 fun consider_general_equals mdata (x as (_, T)) t1 t2 accum = |
918 accum |> (case a of |
|
919 S Minus => accum |
|
920 | S Plus => unsolvable_accum |
|
921 | V x => do_literal (x, Minus) lits) |
|
922 *) |
|
923 |
|
924 (* int -> mtyp -> accumulator -> accumulator *) |
|
925 fun force_minus_funs 0 _ = I |
|
926 | force_minus_funs n (M as MFun (M1, _, M2)) = |
|
927 add_mtypes_equal M (MFun (M1, S Minus, M2)) |
|
928 #> force_minus_funs (n - 1) M2 |
|
929 | force_minus_funs _ M = |
|
930 raise MTYPE ("Nitpick_Mono.force_minus_funs", [M], []) |
|
931 (* mdata -> bool -> styp -> term -> term -> mterm * accumulator *) |
|
932 fun consider_general_equals mdata def (x as (_, T)) t1 t2 accum = |
885 let |
933 let |
886 val (m1, accum) = consider_term mdata t1 accum |
934 val (m1, accum) = consider_term mdata t1 accum |
887 val (m2, accum) = consider_term mdata t2 accum |
935 val (m2, accum) = consider_term mdata t2 accum |
888 val M1 = mtype_of_mterm m1 |
936 val M1 = mtype_of_mterm m1 |
889 val M2 = mtype_of_mterm m2 |
937 val M2 = mtype_of_mterm m2 |
|
938 val accum = accum ||> add_mtypes_equal M1 M2 |
890 val body_M = fresh_mtype_for_type mdata (nth_range_type 2 T) |
939 val body_M = fresh_mtype_for_type mdata (nth_range_type 2 T) |
|
940 val m = MApp (MApp (MRaw (Const x, |
|
941 MFun (M1, S Minus, MFun (M2, S Minus, body_M))), m1), m2) |
891 in |
942 in |
892 (MApp (MApp (MRaw (Const x, |
943 (m, if def then |
893 MFun (M1, S Minus, MFun (M2, S Minus, body_M))), m1), m2), |
944 let val (head_m, arg_ms) = strip_mcomb m1 in |
894 accum ||> add_mtypes_equal M1 M2) |
945 accum ||> force_minus_funs (length arg_ms) (mtype_of_mterm head_m) |
|
946 end |
|
947 else |
|
948 accum) |
895 end |
949 end |
896 |
950 |
897 (* mdata -> sign -> term -> accumulator -> mterm * accumulator *) |
951 (* mdata -> sign -> term -> accumulator -> mterm * accumulator *) |
898 fun consider_general_formula (mdata as {hol_ctxt = {ctxt, ...}, ...}) = |
952 fun consider_general_formula (mdata as {hol_ctxt = {ctxt, ...}, ...}) = |
899 let |
953 let |
910 fun do_quantifier (quant_x as (quant_s, _)) abs_s abs_T body_t = |
964 fun do_quantifier (quant_x as (quant_s, _)) abs_s abs_T body_t = |
911 let |
965 let |
912 val abs_M = mtype_for abs_T |
966 val abs_M = mtype_for abs_T |
913 val side_cond = ((sn = Minus) = (quant_s = @{const_name Ex})) |
967 val side_cond = ((sn = Minus) = (quant_s = @{const_name Ex})) |
914 val (body_m, accum) = |
968 val (body_m, accum) = |
915 accum ||> side_cond ? add_mtype_is_right_total abs_M |
969 accum ||> side_cond ? add_mtype_is_complete abs_M |
916 |>> push_bound abs_M |> do_formula sn body_t |
970 |>> push_bound abs_T abs_M |> do_formula sn body_t |
917 val body_M = mtype_of_mterm body_m |
971 val body_M = mtype_of_mterm body_m |
918 in |
972 in |
919 (MApp (MRaw (Const quant_x, MFun (abs_M, S Minus, body_M)), |
973 (MApp (MRaw (Const quant_x, |
|
974 MFun (MFun (abs_M, S Minus, body_M), S Minus, |
|
975 body_M)), |
920 MAbs (abs_s, abs_T, abs_M, S Minus, body_m)), |
976 MAbs (abs_s, abs_T, abs_M, S Minus, body_m)), |
921 accum |>> pop_bound) |
977 accum |>> pop_bound) |
922 end |
978 end |
923 (* styp -> term -> term -> mterm * accumulator *) |
979 (* styp -> term -> term -> mterm * accumulator *) |
924 fun do_equals x t1 t2 = |
980 fun do_equals x t1 t2 = |
925 case sn of |
981 case sn of |
926 Plus => do_term t accum |
982 Plus => do_term t accum |
927 | Minus => consider_general_equals mdata x t1 t2 accum |
983 | Minus => consider_general_equals mdata false x t1 t2 accum |
928 in |
984 in |
929 case t of |
985 case t of |
930 Const (x as (@{const_name all}, _)) $ Abs (s1, T1, t1) => |
986 Const (x as (@{const_name all}, _)) $ Abs (s1, T1, t1) => |
931 do_quantifier x s1 T1 t1 |
987 do_quantifier x s1 T1 t1 |
932 | Const (x as (@{const_name "=="}, _)) $ t1 $ t2 => do_equals x t1 t2 |
988 | Const (x as (@{const_name "=="}, _)) $ t1 $ t2 => do_equals x t1 t2 |
979 of (rather peculiar) user-defined axioms. *) |
1035 of (rather peculiar) user-defined axioms. *) |
980 val harmless_consts = |
1036 val harmless_consts = |
981 [@{const_name ord_class.less}, @{const_name ord_class.less_eq}] |
1037 [@{const_name ord_class.less}, @{const_name ord_class.less_eq}] |
982 val bounteous_consts = [@{const_name bisim}] |
1038 val bounteous_consts = [@{const_name bisim}] |
983 |
1039 |
984 (* term -> bool *) |
1040 (* mdata -> term -> bool *) |
985 fun is_harmless_axiom ({thy, stds, fast_descrs, ...} : hol_context) t = |
1041 fun is_harmless_axiom ({no_harmless = true, ...} : mdata) _ = false |
986 Term.add_consts t [] |
1042 | is_harmless_axiom {hol_ctxt = {thy, stds, fast_descrs, ...}, ...} t = |
987 |> filter_out (is_built_in_const thy stds fast_descrs) |
1043 Term.add_consts t [] |
988 |> (forall (member (op =) harmless_consts o original_name o fst) |
1044 |> filter_out (is_built_in_const thy stds fast_descrs) |
989 orf exists (member (op =) bounteous_consts o fst)) |
1045 |> (forall (member (op =) harmless_consts o original_name o fst) orf |
|
1046 exists (member (op =) bounteous_consts o fst)) |
990 |
1047 |
991 (* mdata -> term -> accumulator -> mterm * accumulator *) |
1048 (* mdata -> term -> accumulator -> mterm * accumulator *) |
992 fun consider_nondefinitional_axiom (mdata as {hol_ctxt, ...}) t = |
1049 fun consider_nondefinitional_axiom mdata t = |
993 if is_harmless_axiom hol_ctxt t then pair (MRaw (t, dummy_M)) |
1050 if is_harmless_axiom mdata t then pair (MRaw (t, dummy_M)) |
994 else consider_general_formula mdata Plus t |
1051 else consider_general_formula mdata Plus t |
995 |
1052 |
996 (* mdata -> term -> accumulator -> mterm * accumulator *) |
1053 (* mdata -> term -> accumulator -> mterm * accumulator *) |
997 fun consider_definitional_axiom (mdata as {hol_ctxt as {thy, ...}, ...}) t = |
1054 fun consider_definitional_axiom (mdata as {hol_ctxt = {thy, ...}, ...}) t = |
998 if not (is_constr_pattern_formula thy t) then |
1055 if not (is_constr_pattern_formula thy t) then |
999 consider_nondefinitional_axiom mdata t |
1056 consider_nondefinitional_axiom mdata t |
1000 else if is_harmless_axiom hol_ctxt t then |
1057 else if is_harmless_axiom mdata t then |
1001 pair (MRaw (t, dummy_M)) |
1058 pair (MRaw (t, dummy_M)) |
1002 else |
1059 else |
1003 let |
1060 let |
1004 (* typ -> mtyp *) |
1061 (* typ -> mtyp *) |
1005 val mtype_for = fresh_mtype_for_type mdata |
1062 val mtype_for = fresh_mtype_for_type mdata |
1037 (MRaw (t, dummy_M), unsolvable_accum) |
1095 (MRaw (t, dummy_M), unsolvable_accum) |
1038 | do_formula t accum = |
1096 | do_formula t accum = |
1039 case t of |
1097 case t of |
1040 (t0 as Const (@{const_name all}, _)) $ Abs (s1, T1, t1) => |
1098 (t0 as Const (@{const_name all}, _)) $ Abs (s1, T1, t1) => |
1041 do_all t0 s1 T1 t1 accum |
1099 do_all t0 s1 T1 t1 accum |
1042 | @{const Trueprop} $ t1 => do_formula t1 accum |
1100 | @{const Trueprop} $ t1 => |
|
1101 let val (m1, accum) = do_formula t1 accum in |
|
1102 (MApp (MRaw (@{const Trueprop}, mtype_for (bool_T --> prop_T)), |
|
1103 m1), accum) |
|
1104 end |
1043 | Const (x as (@{const_name "=="}, _)) $ t1 $ t2 => |
1105 | Const (x as (@{const_name "=="}, _)) $ t1 $ t2 => |
1044 consider_general_equals mdata x t1 t2 accum |
1106 consider_general_equals mdata true x t1 t2 accum |
1045 | (t0 as @{const "==>"}) $ t1 $ t2 => do_implies t0 t1 t2 accum |
1107 | (t0 as @{const "==>"}) $ t1 $ t2 => do_implies t0 t1 t2 accum |
1046 | (t0 as @{const Pure.conjunction}) $ t1 $ t2 => |
1108 | (t0 as @{const Pure.conjunction}) $ t1 $ t2 => |
1047 do_conjunction t0 t1 t2 accum |
1109 do_conjunction t0 t1 t2 accum |
1048 | (t0 as Const (@{const_name All}, _)) $ Abs (s0, T1, t1) => |
1110 | (t0 as Const (@{const_name All}, _)) $ Abs (s0, T1, t1) => |
1049 do_all t0 s0 T1 t1 accum |
1111 do_all t0 s0 T1 t1 accum |
1050 | Const (x as (@{const_name "op ="}, _)) $ t1 $ t2 => |
1112 | Const (x as (@{const_name "op ="}, _)) $ t1 $ t2 => |
1051 consider_general_equals mdata x t1 t2 accum |
1113 consider_general_equals mdata true x t1 t2 accum |
1052 | (t0 as @{const "op &"}) $ t1 $ t2 => do_conjunction t0 t1 t2 accum |
1114 | (t0 as @{const "op &"}) $ t1 $ t2 => do_conjunction t0 t1 t2 accum |
1053 | (t0 as @{const "op -->"}) $ t1 $ t2 => do_implies t0 t1 t2 accum |
1115 | (t0 as @{const "op -->"}) $ t1 $ t2 => do_implies t0 t1 t2 accum |
1054 | _ => raise TERM ("Nitpick_Mono.consider_definitional_axiom.\ |
1116 | _ => raise TERM ("Nitpick_Mono.consider_definitional_axiom.\ |
1055 \do_formula", [t]) |
1117 \do_formula", [t]) |
1056 in do_formula t end |
1118 in do_formula t end |
1057 |
1119 |
1058 (* Proof.context -> literal list -> term -> mtyp -> string *) |
1120 (* Proof.context -> literal list -> term -> mtyp -> string *) |
1059 fun string_for_mtype_of_term ctxt lits t M = |
1121 fun string_for_mtype_of_term ctxt lits t M = |
1060 Syntax.string_of_term ctxt t ^ " : " ^ |
1122 Syntax.string_of_term ctxt t ^ " : " ^ string_for_mtype (resolve_mtype lits M) |
1061 string_for_mtype (instantiate_mtype lits M) |
|
1062 |
1123 |
1063 (* theory -> literal list -> mtype_context -> unit *) |
1124 (* theory -> literal list -> mtype_context -> unit *) |
1064 fun print_mtype_context ctxt lits ({frees, consts, ...} : mtype_context) = |
1125 fun print_mtype_context ctxt lits ({frees, consts, ...} : mtype_context) = |
1065 map (fn (x, M) => string_for_mtype_of_term ctxt lits (Free x) M) frees @ |
1126 map (fn (x, M) => string_for_mtype_of_term ctxt lits (Free x) M) frees @ |
1066 map (fn (x, M) => string_for_mtype_of_term ctxt lits (Const x) M) consts |
1127 map (fn (x, M) => string_for_mtype_of_term ctxt lits (Const x) M) consts |
1067 |> cat_lines |> print_g |
1128 |> cat_lines |> print_g |
1068 |
1129 |
1069 (* ('a -> 'b -> 'c * 'd) -> 'a -> 'c list * 'b -> 'c list * 'd *) |
1130 (* ('a -> 'b -> 'c * 'd) -> 'a -> 'c list * 'b -> 'c list * 'd *) |
1070 fun gather f t (ms, accum) = |
1131 fun amass f t (ms, accum) = |
1071 let val (m, accum) = f t accum in (m :: ms, accum) end |
1132 let val (m, accum) = f t accum in (m :: ms, accum) end |
1072 |
1133 |
1073 (* hol_context -> bool -> typ -> term list * term list -> bool *) |
1134 (* string -> bool -> hol_context -> bool -> typ -> term list * term list |
1074 fun formulas_monotonic (hol_ctxt as {ctxt, ...}) binarize alpha_T |
1135 -> (literal list * (mterm list * mterm list) * (styp * mtyp) list) option *) |
1075 (nondef_ts, def_ts) = |
1136 fun infer which no_harmless (hol_ctxt as {ctxt, ...}) binarize alpha_T |
|
1137 (nondef_ts, def_ts) = |
1076 let |
1138 let |
1077 val _ = print_g ("****** Monotonicity analysis: " ^ |
1139 val _ = print_g ("****** " ^ which ^ " analysis: " ^ |
1078 string_for_mtype MAlpha ^ " is " ^ |
1140 string_for_mtype MAlpha ^ " is " ^ |
1079 Syntax.string_of_typ ctxt alpha_T) |
1141 Syntax.string_of_typ ctxt alpha_T) |
1080 val mdata as {max_fresh, constr_cache, ...} = |
1142 val mdata as {max_fresh, constr_mcache, ...} = |
1081 initial_mdata hol_ctxt binarize alpha_T |
1143 initial_mdata hol_ctxt binarize no_harmless alpha_T |
1082 |
|
1083 val accum = (initial_gamma, slack) |
1144 val accum = (initial_gamma, slack) |
1084 val (nondef_ms, accum) = |
1145 val (nondef_ms, accum) = |
1085 ([], accum) |> gather (consider_general_formula mdata Plus) (hd nondef_ts) |
1146 ([], accum) |> amass (consider_general_formula mdata Plus) (hd nondef_ts) |
1086 |> fold (gather (consider_nondefinitional_axiom mdata)) |
1147 |> fold (amass (consider_nondefinitional_axiom mdata)) |
1087 (tl nondef_ts) |
1148 (tl nondef_ts) |
1088 val (def_ms, (gamma, cset)) = |
1149 val (def_ms, (gamma, cset)) = |
1089 ([], accum) |> fold (gather (consider_definitional_axiom mdata)) def_ts |
1150 ([], accum) |> fold (amass (consider_definitional_axiom mdata)) def_ts |
1090 in |
1151 in |
1091 case solve (!max_fresh) cset of |
1152 case solve (!max_fresh) cset of |
1092 SOME lits => (print_mtype_context ctxt lits gamma; true) |
1153 SOME lits => (print_mtype_context ctxt lits gamma; |
1093 | _ => false |
1154 SOME (lits, (nondef_ms, def_ms), !constr_mcache)) |
|
1155 | _ => NONE |
1094 end |
1156 end |
1095 handle MTYPE (loc, Ms) => raise BAD (loc, commas (map string_for_mtype Ms)) |
1157 handle MTYPE (loc, Ms, Ts) => |
|
1158 raise BAD (loc, commas (map string_for_mtype Ms @ |
|
1159 map (Syntax.string_of_typ ctxt) Ts)) |
|
1160 | MTERM (loc, ms) => |
|
1161 raise BAD (loc, commas (map (string_for_mterm ctxt) ms)) |
|
1162 |
|
1163 (* hol_context -> bool -> typ -> term list * term list -> bool *) |
|
1164 val formulas_monotonic = is_some oooo infer "Monotonicity" false |
|
1165 |
|
1166 (* typ -> typ -> styp *) |
|
1167 fun fin_fun_constr T1 T2 = |
|
1168 (@{const_name FinFun}, (T1 --> T2) --> Type (@{type_name fin_fun}, [T1, T2])) |
|
1169 |
|
1170 (* hol_context -> bool -> (typ option * bool option) list -> typ |
|
1171 -> term list * term list -> term list * term list *) |
|
1172 fun finitize_funs (hol_ctxt as {thy, stds, fast_descrs, constr_cache, ...}) |
|
1173 binarize finitizes alpha_T tsp = |
|
1174 case infer "Finiteness" true hol_ctxt binarize alpha_T tsp of |
|
1175 SOME (lits, msp, constr_mtypes) => |
|
1176 let |
|
1177 (* typ -> sign_atom -> bool *) |
|
1178 fun should_finitize T a = |
|
1179 case triple_lookup (type_match thy) finitizes T of |
|
1180 SOME (SOME false) => false |
|
1181 | _ => resolve_sign_atom lits a = S Plus |
|
1182 (* typ -> mtyp -> typ *) |
|
1183 fun type_from_mtype T M = |
|
1184 case (M, T) of |
|
1185 (MAlpha, _) => T |
|
1186 | (MFun (M1, a, M2), Type (@{type_name fun}, Ts)) => |
|
1187 Type (if should_finitize T a then @{type_name fin_fun} |
|
1188 else @{type_name fun}, map2 type_from_mtype Ts [M1, M2]) |
|
1189 | (MPair (M1, M2), Type (@{type_name "*"}, Ts)) => |
|
1190 Type (@{type_name "*"}, map2 type_from_mtype Ts [M1, M2]) |
|
1191 | (MType _, _) => T |
|
1192 | _ => raise MTYPE ("Nitpick_Mono.finitize_funs.type_from_mtype", |
|
1193 [M], [T]) |
|
1194 (* styp -> styp *) |
|
1195 fun finitize_constr (x as (s, T)) = |
|
1196 (s, case AList.lookup (op =) constr_mtypes x of |
|
1197 SOME M => type_from_mtype T M |
|
1198 | NONE => T) |
|
1199 (* typ list -> mterm -> term *) |
|
1200 fun term_from_mterm Ts m = |
|
1201 case m of |
|
1202 MRaw (t, M) => |
|
1203 let |
|
1204 val T = fastype_of1 (Ts, t) |
|
1205 val T' = type_from_mtype T M |
|
1206 in |
|
1207 case t of |
|
1208 Const (x as (s, T)) => |
|
1209 if member (op =) [@{const_name "=="}, @{const_name "op ="}] s then |
|
1210 Const (s, T') |
|
1211 else if is_built_in_const thy stds fast_descrs x then |
|
1212 coerce_term hol_ctxt Ts T' T t |
|
1213 else if is_constr thy stds x then |
|
1214 Const (finitize_constr x) |
|
1215 else if is_sel s then |
|
1216 let |
|
1217 val n = sel_no_from_name s |
|
1218 val x' = x |> binarized_and_boxed_constr_for_sel hol_ctxt |
|
1219 binarize |
|
1220 |> finitize_constr |
|
1221 val x'' = binarized_and_boxed_nth_sel_for_constr hol_ctxt |
|
1222 binarize x' n |
|
1223 in Const x'' end |
|
1224 else |
|
1225 Const (s, T') |
|
1226 | Free (s, T) => Free (s, type_from_mtype T M) |
|
1227 | Bound _ => t |
|
1228 | _ => raise MTERM ("Nitpick_Mono.finitize_funs.term_from_mterm", |
|
1229 [m]) |
|
1230 end |
|
1231 | MAbs (s, T, M, a, m') => |
|
1232 let |
|
1233 val T = type_from_mtype T M |
|
1234 val t' = term_from_mterm (T :: Ts) m' |
|
1235 val T' = fastype_of1 (T :: Ts, t') |
|
1236 in |
|
1237 Abs (s, T, t') |
|
1238 |> should_finitize (T --> T') a |
|
1239 ? construct_value thy stds (fin_fun_constr T T') o single |
|
1240 end |
|
1241 | MApp (m1, m2) => |
|
1242 let |
|
1243 val (t1, t2) = pairself (term_from_mterm Ts) (m1, m2) |
|
1244 val (T1, T2) = pairself (curry fastype_of1 Ts) (t1, t2) |
|
1245 val (t1', T2') = |
|
1246 case T1 of |
|
1247 Type (s, [T11, T12]) => |
|
1248 (if s = @{type_name fin_fun} then |
|
1249 select_nth_constr_arg thy stds (fin_fun_constr T11 T12) t1 0 |
|
1250 (T11 --> T12) |
|
1251 else |
|
1252 t1, T11) |
|
1253 | _ => raise TYPE ("Nitpick_Mono.finitize_funs.term_from_mterm", |
|
1254 [T1], []) |
|
1255 in betapply (t1', coerce_term hol_ctxt Ts T2' T2 t2) end |
|
1256 in |
|
1257 Unsynchronized.change constr_cache (map (apsnd (map finitize_constr))); |
|
1258 pairself (map (term_from_mterm [])) msp |
|
1259 end |
|
1260 | NONE => tsp |
1096 |
1261 |
1097 end; |
1262 end; |