1 (* Title: Pure/primitive_defs.ML
4 Primitive definition forms.
7 signature PRIMITIVE_DEFS =
9 val dest_def: Proof.context -> (term -> bool) -> (string -> bool) -> (string -> bool) ->
10 term -> (term * term) * term
11 val abs_def: term -> term * term
14 structure Primitive_Defs: PRIMITIVE_DEFS =
17 fun term_kind (Const _) = "existing constant "
18 | term_kind (Free _) = "free variable "
19 | term_kind (Bound _) = "bound variable "
22 (*c x == t[x] to !!x. c x == t[x]*)
23 fun dest_def ctxt check_head is_fixed is_fixedT eq =
25 fun err msg = raise TERM (msg, [eq]);
26 val eq_vars = Term.strip_all_vars eq;
27 val eq_body = Term.strip_all_body eq;
30 commas_quote o map (Syntax.string_of_term ctxt o Syntax_Trans.bound_vars eq_vars);
31 val display_types = commas_quote o map (Syntax.string_of_typ ctxt);
33 val (raw_lhs, rhs) = Logic.dest_equals eq_body handle TERM _ => err "Not a meta-equality (==)";
34 val lhs = Envir.beta_eta_contract raw_lhs;
35 val (head, args) = Term.strip_comb lhs;
36 val head_tfrees = Term.add_tfrees head [];
38 fun check_arg (Bound _) = true
39 | check_arg (Free (x, _)) = not (is_fixed x)
40 | check_arg (Const ("TYPE", Type ("itself", [TFree _]))) = true
41 | check_arg _ = false;
42 fun close_arg (Bound _) t = t
43 | close_arg x t = Logic.all x t;
45 val lhs_bads = filter_out check_arg args;
46 val lhs_dups = duplicates (op aconv) args;
47 val rhs_extras = Term.fold_aterms (fn v as Free (x, _) =>
48 if is_fixed x orelse member (op aconv) args v then I
49 else insert (op aconv) v | _ => I) rhs [];
50 val rhs_extrasT = Term.fold_aterms (Term.fold_types (fn v as TFree (a, S) =>
51 if is_fixedT a orelse member (op =) head_tfrees (a, S) then I
52 else insert (op =) v | _ => I)) rhs [];
54 if not (check_head head) then
55 err ("Bad head of lhs: " ^ term_kind head ^ display_terms [head])
56 else if not (null lhs_bads) then
57 err ("Bad arguments on lhs: " ^ display_terms lhs_bads)
58 else if not (null lhs_dups) then
59 err ("Duplicate arguments on lhs: " ^ display_terms lhs_dups)
60 else if not (null rhs_extras) then
61 err ("Extra variables on rhs: " ^ display_terms rhs_extras)
62 else if not (null rhs_extrasT) then
63 err ("Extra type variables on rhs: " ^ display_types rhs_extrasT)
64 else if exists_subterm (fn t => t aconv head) rhs then
65 err "Entity to be defined occurs on rhs"
67 ((lhs, rhs), fold_rev close_arg args (Logic.list_all (eq_vars, (Logic.mk_equals (lhs, rhs)))))
70 (*!!x. c x == t[x] to c == %x. t[x]*)
73 val body = Term.strip_all_body eq;
74 val vars = map Free (Term.rename_wrt_term body (Term.strip_all_vars eq));
75 val (lhs, rhs) = Logic.dest_equals (Term.subst_bounds (vars, body));
76 val (lhs', args) = Term.strip_comb lhs;
77 val rhs' = fold_rev (absfree o dest_Free) args rhs;