27 |
26 |
28 val abs_iso_ax = ("abs_iso", mk_trp(dc_rep`(dc_abs`%x_name') === %:x_name')); |
27 val abs_iso_ax = ("abs_iso", mk_trp(dc_rep`(dc_abs`%x_name') === %:x_name')); |
29 val rep_iso_ax = ("rep_iso", mk_trp(dc_abs`(dc_rep`%x_name') === %:x_name')); |
28 val rep_iso_ax = ("rep_iso", mk_trp(dc_abs`(dc_rep`%x_name') === %:x_name')); |
30 |
29 |
31 val when_def = ("when_def",%%:(dname^"_when") == |
30 val when_def = ("when_def",%%:(dname^"_when") == |
32 foldr (uncurry /\ ) (/\x_name'((when_body cons (fn (x,y) => |
31 List.foldr (uncurry /\ ) (/\x_name'((when_body cons (fn (x,y) => |
33 Bound(1+length cons+x-y)))`(dc_rep`Bound 0))) (when_funs cons)); |
32 Bound(1+length cons+x-y)))`(dc_rep`Bound 0))) (when_funs cons)); |
34 |
33 |
35 val copy_def = let |
34 val copy_def = let |
36 fun idxs z x arg = if is_rec arg |
35 fun idxs z x arg = if is_rec arg |
37 then (cproj (Bound z) eqs (rec_of arg))`Bound(z-x) |
36 then (cproj (Bound z) eqs (rec_of arg))`Bound(z-x) |
38 else Bound(z-x); |
37 else Bound(z-x); |
39 fun one_con (con,args) = |
38 fun one_con (con,args) = |
40 foldr /\# (list_ccomb (%%:con, mapn (idxs (length args)) 1 args)) args; |
39 List.foldr /\# (list_ccomb (%%:con, mapn (idxs (length args)) 1 args)) args; |
41 in ("copy_def", %%:(dname^"_copy") == |
40 in ("copy_def", %%:(dname^"_copy") == |
42 /\"f" (list_ccomb (%%:(dname^"_when"), map one_con cons))) end; |
41 /\ "f" (list_ccomb (%%:(dname^"_when"), map one_con cons))) end; |
43 |
42 |
44 (* -- definitions concerning the constructors, discriminators and selectors - *) |
43 (* -- definitions concerning the constructors, discriminators and selectors - *) |
45 |
44 |
46 fun con_def m n (_,args) = let |
45 fun con_def m n (_,args) = let |
47 fun idxs z x arg = (if is_lazy arg then mk_up else I) (Bound(z-x)); |
46 fun idxs z x arg = (if is_lazy arg then mk_up else I) (Bound(z-x)); |
48 fun parms vs = mk_stuple (mapn (idxs(length vs)) 1 vs); |
47 fun parms vs = mk_stuple (mapn (idxs(length vs)) 1 vs); |
49 fun inj y 1 _ = y |
48 fun inj y 1 _ = y |
50 | inj y _ 0 = mk_sinl y |
49 | inj y _ 0 = mk_sinl y |
51 | inj y i j = mk_sinr (inj y (i-1) (j-1)); |
50 | inj y i j = mk_sinr (inj y (i-1) (j-1)); |
52 in foldr /\# (dc_abs`(inj (parms args) m n)) args end; |
51 in List.foldr /\# (dc_abs`(inj (parms args) m n)) args end; |
53 |
52 |
54 val con_defs = mapn (fn n => fn (con,args) => |
53 val con_defs = mapn (fn n => fn (con,args) => |
55 (extern_name con ^"_def", %%:con == con_def (length cons) n (con,args))) 0 cons; |
54 (extern_name con ^"_def", %%:con == con_def (length cons) n (con,args))) 0 cons; |
56 |
55 |
57 val dis_defs = let |
56 val dis_defs = let |
58 fun ddef (con,_) = (dis_name con ^"_def",%%:(dis_name con) == |
57 fun ddef (con,_) = (dis_name con ^"_def",%%:(dis_name con) == |
59 list_ccomb(%%:(dname^"_when"),map |
58 list_ccomb(%%:(dname^"_when"),map |
60 (fn (con',args) => (foldr /\# |
59 (fn (con',args) => (List.foldr /\# |
61 (if con'=con then TT else FF) args)) cons)) |
60 (if con'=con then TT else FF) args)) cons)) |
62 in map ddef cons end; |
61 in map ddef cons end; |
63 |
62 |
64 val mat_defs = let |
63 val mat_defs = let |
65 fun mdef (con,_) = (mat_name con ^"_def",%%:(mat_name con) == |
64 fun mdef (con,_) = (mat_name con ^"_def",%%:(mat_name con) == |
66 list_ccomb(%%:(dname^"_when"),map |
65 list_ccomb(%%:(dname^"_when"),map |
67 (fn (con',args) => (foldr /\# |
66 (fn (con',args) => (List.foldr /\# |
68 (if con'=con |
67 (if con'=con |
69 then mk_return (mk_ctuple (map (bound_arg args) args)) |
68 then mk_return (mk_ctuple (map (bound_arg args) args)) |
70 else mk_fail) args)) cons)) |
69 else mk_fail) args)) cons)) |
71 in map mdef cons end; |
70 in map mdef cons end; |
72 |
71 |
77 val ps = mapn (fn n => fn _ => %:("pat" ^ string_of_int n)) 1 args; |
76 val ps = mapn (fn n => fn _ => %:("pat" ^ string_of_int n)) 1 args; |
78 val xs = map (bound_arg args) args; |
77 val xs = map (bound_arg args) args; |
79 val r = Bound (length args); |
78 val r = Bound (length args); |
80 val rhs = case args of [] => mk_return HOLogic.unit |
79 val rhs = case args of [] => mk_return HOLogic.unit |
81 | _ => mk_ctuple_pat ps ` mk_ctuple xs; |
80 | _ => mk_ctuple_pat ps ` mk_ctuple xs; |
82 fun one_con (con',args') = foldr /\# (if con'=con then rhs else mk_fail) args'; |
81 fun one_con (con',args') = List.foldr /\# (if con'=con then rhs else mk_fail) args'; |
83 in (pat_name con ^"_def", list_comb (%%:(pat_name con), ps) == |
82 in (pat_name con ^"_def", list_comb (%%:(pat_name con), ps) == |
84 list_ccomb(%%:(dname^"_when"), map one_con cons)) |
83 list_ccomb(%%:(dname^"_when"), map one_con cons)) |
85 end |
84 end |
86 in map pdef cons end; |
85 in map pdef cons end; |
87 |
86 |
88 val sel_defs = let |
87 val sel_defs = let |
89 fun sdef con n arg = Option.map (fn sel => (sel^"_def",%%:sel == |
88 fun sdef con n arg = Option.map (fn sel => (sel^"_def",%%:sel == |
90 list_ccomb(%%:(dname^"_when"),map |
89 list_ccomb(%%:(dname^"_when"),map |
91 (fn (con',args) => if con'<>con then UU else |
90 (fn (con',args) => if con'<>con then UU else |
92 foldr /\# (Bound (length args - n)) args) cons))) (sel_of arg); |
91 List.foldr /\# (Bound (length args - n)) args) cons))) (sel_of arg); |
93 in List.mapPartial I (List.concat(map (fn (con,args) => mapn (sdef con) 1 args) cons)) end; |
92 in List.mapPartial I (List.concat(map (fn (con,args) => mapn (sdef con) 1 args) cons)) end; |
94 |
93 |
95 |
94 |
96 (* ----- axiom and definitions concerning induction ------------------------- *) |
95 (* ----- axiom and definitions concerning induction ------------------------- *) |
97 |
96 |
105 in (dnam, |
104 in (dnam, |
106 [abs_iso_ax, rep_iso_ax, reach_ax], |
105 [abs_iso_ax, rep_iso_ax, reach_ax], |
107 [when_def, copy_def] @ |
106 [when_def, copy_def] @ |
108 con_defs @ dis_defs @ mat_defs @ pat_defs @ sel_defs @ |
107 con_defs @ dis_defs @ mat_defs @ pat_defs @ sel_defs @ |
109 [take_def, finite_def]) |
108 [take_def, finite_def]) |
110 end; (* let *) |
109 end; (* let (calc_axioms) *) |
111 |
110 |
112 fun infer_props thy = map (apsnd (FixrecPackage.legacy_infer_prop thy)); |
111 fun infer_props thy = map (apsnd (FixrecPackage.legacy_infer_prop thy)); |
113 |
112 |
114 fun add_axioms_i x = snd o PureThy.add_axioms (map (Thm.no_attributes o apfst Binding.name) x); |
113 fun add_axioms_i x = snd o PureThy.add_axioms (map (Thm.no_attributes o apfst Binding.name) x); |
115 fun add_axioms_infer axms thy = add_axioms_i (infer_props thy axms) thy; |
114 fun add_axioms_infer axms thy = add_axioms_i (infer_props thy axms) thy; |
116 |
115 |
117 fun add_defs_i x = snd o (PureThy.add_defs false) (map (Thm.no_attributes o apfst Binding.name) x); |
116 fun add_defs_i x = snd o (PureThy.add_defs false) (map (Thm.no_attributes o apfst Binding.name) x); |
118 fun add_defs_infer defs thy = add_defs_i (infer_props thy defs) thy; |
117 fun add_defs_infer defs thy = add_defs_i (infer_props thy defs) thy; |
119 |
118 |
|
119 fun add_matchers (((dname,_),cons) : eq) thy = |
|
120 let |
|
121 val con_names = map fst cons; |
|
122 val mat_names = map mat_name con_names; |
|
123 fun qualify n = Sign.full_name thy (Binding.name n); |
|
124 val ms = map qualify con_names ~~ map qualify mat_names; |
|
125 in FixrecPackage.add_matchers ms thy end; |
|
126 |
120 in (* local *) |
127 in (* local *) |
121 |
128 |
122 fun add_axioms (comp_dnam, eqs : eq list) thy' = let |
129 fun add_axioms (comp_dnam, eqs : eq list) thy' = let |
123 val comp_dname = Sign.full_bname thy' comp_dnam; |
130 val comp_dname = Sign.full_bname thy' comp_dnam; |
124 val dnames = map (fst o fst) eqs; |
131 val dnames = map (fst o fst) eqs; |
125 val x_name = idx_name dnames "x"; |
132 val x_name = idx_name dnames "x"; |
126 fun copy_app dname = %%:(dname^"_copy")`Bound 0; |
133 fun copy_app dname = %%:(dname^"_copy")`Bound 0; |
127 val copy_def = ("copy_def" , %%:(comp_dname^"_copy") == |
134 val copy_def = ("copy_def" , %%:(comp_dname^"_copy") == |
128 /\"f"(mk_ctuple (map copy_app dnames))); |
135 /\ "f"(mk_ctuple (map copy_app dnames))); |
129 val bisim_def = ("bisim_def",%%:(comp_dname^"_bisim")==mk_lam("R", |
136 val bisim_def = ("bisim_def",%%:(comp_dname^"_bisim")==mk_lam("R", |
130 let |
137 let |
131 fun one_con (con,args) = let |
138 fun one_con (con,args) = let |
132 val nonrec_args = filter_out is_rec args; |
139 val nonrec_args = filter_out is_rec args; |
133 val rec_args = List.filter is_rec args; |
140 val rec_args = List.filter is_rec args; |
142 val rec_idxs = (recs_cnt-1) downto 0; |
149 val rec_idxs = (recs_cnt-1) downto 0; |
143 val nonlazy_idxs = map snd (filter_out (fn (arg,_) => is_lazy arg) |
150 val nonlazy_idxs = map snd (filter_out (fn (arg,_) => is_lazy arg) |
144 (allargs~~((allargs_cnt-1) downto 0))); |
151 (allargs~~((allargs_cnt-1) downto 0))); |
145 fun rel_app i ra = proj (Bound(allargs_cnt+2)) eqs (rec_of ra) $ |
152 fun rel_app i ra = proj (Bound(allargs_cnt+2)) eqs (rec_of ra) $ |
146 Bound (2*recs_cnt-i) $ Bound (recs_cnt-i); |
153 Bound (2*recs_cnt-i) $ Bound (recs_cnt-i); |
147 val capps = foldr mk_conj (mk_conj( |
154 val capps = List.foldr mk_conj (mk_conj( |
148 Bound(allargs_cnt+1)===list_ccomb(%%:con,map (bound_arg allvns) vns1), |
155 Bound(allargs_cnt+1)===list_ccomb(%%:con,map (bound_arg allvns) vns1), |
149 Bound(allargs_cnt+0)===list_ccomb(%%:con,map (bound_arg allvns) vns2))) |
156 Bound(allargs_cnt+0)===list_ccomb(%%:con,map (bound_arg allvns) vns2))) |
150 (mapn rel_app 1 rec_args); |
157 (mapn rel_app 1 rec_args); |
151 in foldr mk_ex (Library.foldr mk_conj |
158 in List.foldr mk_ex (Library.foldr mk_conj |
152 (map (defined o Bound) nonlazy_idxs,capps)) allvns end; |
159 (map (defined o Bound) nonlazy_idxs,capps)) allvns end; |
153 fun one_comp n (_,cons) =mk_all(x_name(n+1),mk_all(x_name(n+1)^"'",mk_imp( |
160 fun one_comp n (_,cons) =mk_all(x_name(n+1),mk_all(x_name(n+1)^"'",mk_imp( |
154 proj (Bound 2) eqs n $ Bound 1 $ Bound 0, |
161 proj (Bound 2) eqs n $ Bound 1 $ Bound 0, |
155 foldr1 mk_disj (mk_conj(Bound 1 === UU,Bound 0 === UU) |
162 foldr1 mk_disj (mk_conj(Bound 1 === UU,Bound 0 === UU) |
156 ::map one_con cons)))); |
163 ::map one_con cons)))); |