237 (* prove strictness rules for constructors *) |
237 (* prove strictness rules for constructors *) |
238 local |
238 local |
239 fun con_strict (con, args) = |
239 fun con_strict (con, args) = |
240 let |
240 let |
241 val rules = abs_strict :: @{thms con_strict_rules}; |
241 val rules = abs_strict :: @{thms con_strict_rules}; |
242 val vs = vars_of args; |
242 val (vs, nonlazy) = get_vars args; |
243 val nonlazy = map snd (filter_out fst (map fst args ~~ vs)); |
|
244 fun one_strict v' = |
243 fun one_strict v' = |
245 let |
244 let |
246 val UU = mk_bottom (fastype_of v'); |
245 val UU = mk_bottom (fastype_of v'); |
247 val vs' = map (fn v => if v = v' then UU else v) vs; |
246 val vs' = map (fn v => if v = v' then UU else v) vs; |
248 val goal = mk_trp (mk_undef (list_ccomb (con, vs'))); |
247 val goal = mk_trp (mk_undef (list_ccomb (con, vs'))); |
252 |
251 |
253 fun con_defin (con, args) = |
252 fun con_defin (con, args) = |
254 let |
253 let |
255 fun iff_disj (t, []) = HOLogic.mk_not t |
254 fun iff_disj (t, []) = HOLogic.mk_not t |
256 | iff_disj (t, ts) = mk_eq (t, foldr1 HOLogic.mk_disj ts); |
255 | iff_disj (t, ts) = mk_eq (t, foldr1 HOLogic.mk_disj ts); |
257 val vs = vars_of args; |
256 val (vs, nonlazy) = get_vars args; |
258 val nonlazy = map snd (filter_out fst (map fst args ~~ vs)); |
|
259 val lhs = mk_undef (list_ccomb (con, vs)); |
257 val lhs = mk_undef (list_ccomb (con, vs)); |
260 val rhss = map mk_undef nonlazy; |
258 val rhss = map mk_undef nonlazy; |
261 val goal = mk_trp (iff_disj (lhs, rhss)); |
259 val goal = mk_trp (iff_disj (lhs, rhss)); |
262 val rule1 = iso_locale RS @{thm iso.abs_defined_iff}; |
260 val rule1 = iso_locale RS @{thm iso.abs_defined_iff}; |
263 val rules = rule1 :: @{thms con_defined_iff_rules}; |
261 val rules = rule1 :: @{thms con_defined_iff_rules}; |
273 local |
271 local |
274 fun pgterm rel (con, args) = |
272 fun pgterm rel (con, args) = |
275 let |
273 let |
276 fun prime (Free (n, T)) = Free (n^"'", T) |
274 fun prime (Free (n, T)) = Free (n^"'", T) |
277 | prime t = t; |
275 | prime t = t; |
278 val xs = vars_of args; |
276 val (xs, nonlazy) = get_vars args; |
279 val ys = map prime xs; |
277 val ys = map prime xs; |
280 val nonlazy = map snd (filter_out (fst o fst) (args ~~ xs)); |
|
281 val lhs = rel (list_ccomb (con, xs), list_ccomb (con, ys)); |
278 val lhs = rel (list_ccomb (con, xs), list_ccomb (con, ys)); |
282 val rhs = foldr1 mk_conj (ListPair.map rel (xs, ys)); |
279 val rhs = foldr1 mk_conj (ListPair.map rel (xs, ys)); |
283 val concl = mk_trp (mk_eq (lhs, rhs)); |
280 val concl = mk_trp (mk_eq (lhs, rhs)); |
284 val zs = case args of [_] => [] | _ => nonlazy; |
281 val zs = case args of [_] => [] | _ => nonlazy; |
285 val assms = map (mk_trp o mk_defined) zs; |
282 val assms = map (mk_trp o mk_defined) zs; |
317 | iff_disj2 (t, ts, []) = mk_not t |
314 | iff_disj2 (t, ts, []) = mk_not t |
318 | iff_disj2 (t, ts, us) = |
315 | iff_disj2 (t, ts, us) = |
319 mk_eq (t, mk_conj (foldr1 mk_disj ts, foldr1 mk_disj us)); |
316 mk_eq (t, mk_conj (foldr1 mk_disj ts, foldr1 mk_disj us)); |
320 fun dist_le (con1, args1) (con2, args2) = |
317 fun dist_le (con1, args1) (con2, args2) = |
321 let |
318 let |
322 val vs1 = vars_of args1; |
319 val (vs1, zs1) = get_vars args1; |
323 val vs2 = map prime (vars_of args2); |
320 val (vs2, zs2) = get_vars args2 |> pairself (map prime); |
324 val zs1 = map snd (filter_out (fst o fst) (args1 ~~ vs1)); |
|
325 val lhs = mk_below (list_ccomb (con1, vs1), list_ccomb (con2, vs2)); |
321 val lhs = mk_below (list_ccomb (con1, vs1), list_ccomb (con2, vs2)); |
326 val rhss = map mk_undef zs1; |
322 val rhss = map mk_undef zs1; |
327 val goal = mk_trp (iff_disj (lhs, rhss)); |
323 val goal = mk_trp (iff_disj (lhs, rhss)); |
328 val rule1 = iso_locale RS @{thm iso.abs_below}; |
324 val rule1 = iso_locale RS @{thm iso.abs_below}; |
329 val rules = rule1 :: @{thms con_below_iff_rules}; |
325 val rules = rule1 :: @{thms con_below_iff_rules}; |
330 val tacs = [simp_tac (HOL_ss addsimps rules) 1]; |
326 val tacs = [simp_tac (HOL_ss addsimps rules) 1]; |
331 in prove thy con_betas goal (K tacs) end; |
327 in prove thy con_betas goal (K tacs) end; |
332 fun dist_eq (con1, args1) (con2, args2) = |
328 fun dist_eq (con1, args1) (con2, args2) = |
333 let |
329 let |
334 val vs1 = vars_of args1; |
330 val (vs1, zs1) = get_vars args1; |
335 val vs2 = map prime (vars_of args2); |
331 val (vs2, zs2) = get_vars args2 |> pairself (map prime); |
336 val zs1 = map snd (filter_out (fst o fst) (args1 ~~ vs1)); |
|
337 val zs2 = map snd (filter_out (fst o fst) (args2 ~~ vs2)); |
|
338 val lhs = mk_eq (list_ccomb (con1, vs1), list_ccomb (con2, vs2)); |
332 val lhs = mk_eq (list_ccomb (con1, vs1), list_ccomb (con2, vs2)); |
339 val rhss1 = map mk_undef zs1; |
333 val rhss1 = map mk_undef zs1; |
340 val rhss2 = map mk_undef zs2; |
334 val rhss2 = map mk_undef zs2; |
341 val goal = mk_trp (iff_disj2 (lhs, rhss1, rhss2)); |
335 val goal = mk_trp (iff_disj2 (lhs, rhss1, rhss2)); |
342 val rule1 = iso_locale RS @{thm iso.abs_eq}; |
336 val rule1 = iso_locale RS @{thm iso.abs_eq}; |