38 end |
38 end |
39 |
39 |
40 fun pred_of_function thy name = |
40 fun pred_of_function thy name = |
41 case Item_Net.retrieve (Fun_Pred.get thy) (Const (name, dummyT)) of |
41 case Item_Net.retrieve (Fun_Pred.get thy) (Const (name, dummyT)) of |
42 [] => NONE |
42 [] => NONE |
43 | [(f, p)] => SOME (fst (dest_Const p)) |
43 | [(_, p)] => SOME (fst (dest_Const p)) |
44 | _ => error ("Multiple matches possible for lookup of constant " ^ name) |
44 | _ => error ("Multiple matches possible for lookup of constant " ^ name) |
45 |
45 |
46 fun defined_const thy name = is_some (pred_of_function thy name) |
46 fun defined_const thy name = is_some (pred_of_function thy name) |
47 |
47 |
48 fun add_function_predicate_translation (f, p) = |
48 fun add_function_predicate_translation (f, p) = |
75 |
75 |
76 fun dest_code_eqn eqn = let |
76 fun dest_code_eqn eqn = let |
77 val (lhs, rhs) = Logic.dest_equals (Logic.unvarify_global (Thm.prop_of eqn)) |
77 val (lhs, rhs) = Logic.dest_equals (Logic.unvarify_global (Thm.prop_of eqn)) |
78 val (func, args) = strip_comb lhs |
78 val (func, args) = strip_comb lhs |
79 in ((func, args), rhs) end; |
79 in ((func, args), rhs) end; |
80 |
|
81 (* TODO: does not work with higher order functions yet *) |
|
82 fun mk_rewr_eq (func, pred) = |
|
83 let |
|
84 val (argTs, resT) = strip_type (fastype_of func) |
|
85 val nctxt = |
|
86 Name.make_context (Term.fold_aterms (fn Free (x, _) => insert (op =) x | _ => I) (func $ pred) []) |
|
87 val (argnames, nctxt') = fold_map Name.variant (replicate (length argTs) "a") nctxt |
|
88 val (resname, nctxt'') = Name.variant "r" nctxt' |
|
89 val args = map Free (argnames ~~ argTs) |
|
90 val res = Free (resname, resT) |
|
91 in Logic.mk_equals |
|
92 (HOLogic.mk_eq (res, list_comb (func, args)), list_comb (pred, args @ [res])) |
|
93 end; |
|
94 |
80 |
95 fun folds_map f xs y = |
81 fun folds_map f xs y = |
96 let |
82 let |
97 fun folds_map' acc [] y = [(rev acc, y)] |
83 fun folds_map' acc [] y = [(rev acc, y)] |
98 | folds_map' acc (x :: xs) y = |
84 | folds_map' acc (x :: xs) y = |
124 |> map (fn (res, (inner_names, inner_prems)) => |
110 |> map (fn (res, (inner_names, inner_prems)) => |
125 let |
111 let |
126 fun mk_exists (x, T) t = HOLogic.mk_exists (x, T, t) |
112 fun mk_exists (x, T) t = HOLogic.mk_exists (x, T, t) |
127 val vTs = |
113 val vTs = |
128 fold Term.add_frees inner_prems [] |
114 fold Term.add_frees inner_prems [] |
129 |> filter (fn (x, T) => member (op =) inner_names x) |
115 |> filter (fn (x, _) => member (op =) inner_names x) |
130 val t = |
116 val t = |
131 fold mk_exists vTs |
117 fold mk_exists vTs |
132 (foldr1 HOLogic.mk_conj (HOLogic.mk_eq (res, resvar) :: |
118 (foldr1 HOLogic.mk_conj (HOLogic.mk_eq (res, resvar) :: |
133 map HOLogic.dest_Trueprop inner_prems)) |
119 map HOLogic.dest_Trueprop inner_prems)) |
134 in |
120 in |
147 if (pred_type (fastype_of t) = T) then |
133 if (pred_type (fastype_of t) = T) then |
148 lift t (names, prems) |
134 lift t (names, prems) |
149 else |
135 else |
150 error ("unexpected input for flatten or lift" ^ Syntax.string_of_term_global thy t ^ |
136 error ("unexpected input for flatten or lift" ^ Syntax.string_of_term_global thy t ^ |
151 ", " ^ Syntax.string_of_typ_global thy T) |
137 ", " ^ Syntax.string_of_typ_global thy T) |
152 and flatten' (t as Const (name, T)) (names, prems) = [(t, (names, prems))] |
138 and flatten' (t as Const _) (names, prems) = [(t, (names, prems))] |
153 | flatten' (t as Free (f, T)) (names, prems) = [(t, (names, prems))] |
139 | flatten' (t as Free _) (names, prems) = [(t, (names, prems))] |
154 | flatten' (t as Abs _) (names, prems) = [(t, (names, prems))] |
140 | flatten' (t as Abs _) (names, prems) = [(t, (names, prems))] |
155 | flatten' (t as _ $ _) (names, prems) = |
141 | flatten' (t as _ $ _) (names, prems) = |
156 if Predicate_Compile_Aux.is_constrt thy t orelse keep_functions thy t then |
142 if Predicate_Compile_Aux.is_constrt thy t orelse keep_functions thy t then |
157 [(t, (names, prems))] |
143 [(t, (names, prems))] |
158 else |
144 else |
180 end) |
166 end) |
181 | _ => |
167 | _ => |
182 case find_split_thm thy (fst (strip_comb t)) of |
168 case find_split_thm thy (fst (strip_comb t)) of |
183 SOME raw_split_thm => |
169 SOME raw_split_thm => |
184 let |
170 let |
185 val (f, args) = strip_comb t |
|
186 val split_thm = prepare_split_thm (Proof_Context.init_global thy) raw_split_thm |
171 val split_thm = prepare_split_thm (Proof_Context.init_global thy) raw_split_thm |
187 val (assms, concl) = Logic.strip_horn (prop_of split_thm) |
172 val (assms, concl) = Logic.strip_horn (prop_of split_thm) |
188 val (P, [split_t]) = strip_comb (HOLogic.dest_Trueprop concl) |
173 val (_, [split_t]) = strip_comb (HOLogic.dest_Trueprop concl) |
189 val t' = case_betapply thy t |
174 val t' = case_betapply thy t |
190 val subst = Pattern.match thy (split_t, t') (Vartab.empty, Vartab.empty) |
175 val subst = Pattern.match thy (split_t, t') (Vartab.empty, Vartab.empty) |
191 fun flatten_of_assm assm = |
176 fun flatten_of_assm assm = |
192 let |
177 let |
193 val (vTs, assm') = strip_all (Envir.beta_norm (Envir.subst_term subst assm)) |
178 val (vTs, assm') = strip_all (Envir.beta_norm (Envir.subst_term subst assm)) |
265 fun define_predicates specs thy = |
250 fun define_predicates specs thy = |
266 if forall (fn (const, _) => defined_const thy const) specs then |
251 if forall (fn (const, _) => defined_const thy const) specs then |
267 ([], thy) |
252 ([], thy) |
268 else |
253 else |
269 let |
254 let |
270 val consts = map fst specs |
|
271 val eqns = maps snd specs |
255 val eqns = maps snd specs |
272 (* create prednames *) |
256 (* create prednames *) |
273 val ((funs, argss), rhss) = map_split dest_code_eqn eqns |>> split_list |
257 val ((funs, argss), rhss) = map_split dest_code_eqn eqns |>> split_list |
274 val dst_funs = distinct (op =) funs |
258 val dst_funs = distinct (op =) funs |
275 val argss' = map (map transform_ho_arg) argss |
259 val argss' = map (map transform_ho_arg) argss |
291 [Logic.list_implies ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))] |
275 [Logic.list_implies ([HOLogic.mk_Trueprop rhs], HOLogic.mk_Trueprop (list_comb (pred, args)))] |
292 else |
276 else |
293 let |
277 let |
294 val names = Term.add_free_names rhs [] |
278 val names = Term.add_free_names rhs [] |
295 in flatten thy lookup_pred rhs (names, []) |
279 in flatten thy lookup_pred rhs (names, []) |
296 |> map (fn (resultt, (names', prems)) => |
280 |> map (fn (resultt, (_, prems)) => |
297 Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt])))) |
281 Logic.list_implies (prems, HOLogic.mk_Trueprop (list_comb (pred, args @ [resultt])))) |
298 end |
282 end |
299 fun mk_rewr_thm (func, pred) = @{thm refl} |
|
300 val intr_ts = maps mk_intros ((funs ~~ preds) ~~ (argss' ~~ rhss)) |
283 val intr_ts = maps mk_intros ((funs ~~ preds) ~~ (argss' ~~ rhss)) |
301 val (intrs, thy') = thy |
284 val (intrs, thy') = thy |
302 |> Sign.add_consts_i |
285 |> Sign.add_consts_i |
303 (map (fn Const (name, T) => (Binding.name (Long_Name.base_name name), T, NoSyn)) |
286 (map (fn Const (name, T) => (Binding.name (Long_Name.base_name name), T, NoSyn)) |
304 dst_preds) |
287 dst_preds) |