1274
|
1 |
(* axioms.ML
|
|
2 |
ID: $Id$
|
|
3 |
Author : David von Oheimb
|
|
4 |
Created: 31-May-95
|
|
5 |
Updated: 12-Jun-95 axioms for discriminators, selectors and induction
|
|
6 |
Updated: 19-Jun-95 axiom for bisimulation
|
|
7 |
Updated: 28-Jul-95 gen_by-section
|
|
8 |
Updated: 29-Aug-95 simultaneous domain equations
|
|
9 |
Copyright 1995 TU Muenchen
|
|
10 |
*)
|
|
11 |
|
|
12 |
|
|
13 |
structure Domain_Axioms = struct
|
|
14 |
|
|
15 |
local
|
|
16 |
|
|
17 |
open Domain_Library;
|
|
18 |
infixr 0 ===>;infixr 0 ==>;infix 0 == ;
|
|
19 |
infix 1 ===; infix 1 ~= ; infix 1 <<; infix 1 ~<<;
|
|
20 |
infix 9 ` ; infix 9 `% ; infix 9 `%%; infixr 9 oo;
|
|
21 |
|
|
22 |
fun infer_types thy' = map (inferT_axm (sign_of thy'));
|
|
23 |
|
|
24 |
fun calc_axioms comp_dname (eqs : eq list) n (((dname,_),cons) : eq)=
|
|
25 |
let
|
|
26 |
|
|
27 |
(* ----- axioms and definitions concerning the isomorphism ------------------------ *)
|
|
28 |
|
|
29 |
val dc_abs = %%(dname^"_abs");
|
|
30 |
val dc_rep = %%(dname^"_rep");
|
|
31 |
val x_name'= "x";
|
|
32 |
val x_name = idx_name eqs x_name' (n+1);
|
|
33 |
|
|
34 |
val ax_abs_iso = (dname^"_abs_iso",mk_trp(dc_rep`(dc_abs`%x_name') === %x_name'));
|
|
35 |
val ax_rep_iso = (dname^"_rep_iso",mk_trp(dc_abs`(dc_rep`%x_name') === %x_name'));
|
|
36 |
|
|
37 |
val ax_when_def = (dname^"_when_def",%%(dname^"_when") ==
|
1461
|
38 |
foldr (uncurry /\ ) (when_funs cons, /\x_name'((when_body cons (fn (x,y) =>
|
|
39 |
Bound(1+length cons+x-y)))`(dc_rep`Bound 0))));
|
1274
|
40 |
|
|
41 |
val ax_copy_def = let
|
|
42 |
fun simp_oo (Const ("fapp", _) $ (Const ("fapp", _) $
|
1461
|
43 |
Const ("cfcomp", _) $ fc) $ Const ("ID", _)) = fc
|
1274
|
44 |
| simp_oo t = t;
|
|
45 |
fun simp_app (Const ("fapp", _) $ Const ("ID", _) $ t) = t
|
|
46 |
| simp_app t = t;
|
1461
|
47 |
fun mk_arg m n arg = (if is_lazy arg
|
|
48 |
then fn t => %%"lift"`(simp_oo (%%"up" oo t)) else Id)
|
|
49 |
(if_rec arg (cproj (Bound (2*min[n,m])) eqs) (%%"ID"));
|
|
50 |
fun mk_prod (t1,t2) = %%"ssplit"`(/\ "x" (/\ "y" (%%"spair"`
|
|
51 |
simp_app(t1`Bound 1)`simp_app(t2`Bound 0))));
|
|
52 |
fun one_con (_,args) = if args = [] then %%"ID" else
|
|
53 |
foldr' mk_prod (mapn (mk_arg (length args-1)) 1 args);
|
|
54 |
fun mk_sum (t1,t2) = %%"sswhen"`(simp_oo (%%"sinl" oo t1))
|
|
55 |
`(simp_oo (%%"sinr" oo t2));
|
|
56 |
in (dname^"_copy_def", %%(dname^"_copy") == /\"f"
|
|
57 |
(dc_abs oo foldr' mk_sum (map one_con cons) oo dc_rep)) end;
|
1274
|
58 |
|
|
59 |
(* ----- definitions concerning the constructors, discriminators and selectors ---- *)
|
|
60 |
|
|
61 |
val axs_con_def = let
|
1461
|
62 |
fun idxs z x arg = (if is_lazy arg then fn x => %%"up"`x else Id)(Bound(z-x));
|
|
63 |
fun prms [] = %%"one"
|
|
64 |
| prms vs = foldr' (fn(x,t)=> %%"spair"`x`t) (mapn (idxs (length vs)) 1 vs);
|
|
65 |
val injs = bin_branchr (fn l=> l@["l"]) (fn l=> l@["r"]);
|
|
66 |
fun cdef ((con,args),injs) = (extern_name con ^"_def",%%con ==
|
|
67 |
foldr /\# (args,dc_abs`
|
|
68 |
(foldr (fn (i,t) => %%("sin"^i)`t ) (injs, prms args))));
|
|
69 |
in map cdef (cons~~(mapn (fn n => K(injs [] cons n)) 0 cons)) end;
|
1274
|
70 |
|
|
71 |
val axs_dis_def = let
|
1461
|
72 |
fun ddef (con,_) = (dis_name con ^"_def",%%(dis_name con) ==
|
|
73 |
mk_cfapp(%%(dname^"_when"),map
|
|
74 |
(fn (con',args) => (foldr /\#
|
|
75 |
(args,if con'=con then %%"TT" else %%"FF"))) cons))
|
|
76 |
in map ddef cons end;
|
1274
|
77 |
|
|
78 |
val axs_sel_def = let
|
1461
|
79 |
fun sdef con n arg = (sel_of arg^"_def",%%(sel_of arg) ==
|
|
80 |
mk_cfapp(%%(dname^"_when"),map
|
|
81 |
(fn (con',args) => if con'<>con then %%"UU" else
|
|
82 |
foldr /\# (args,Bound (length args - n))) cons));
|
|
83 |
in flat(map (fn (con,args) => mapn (sdef con) 1 args) cons) end;
|
1274
|
84 |
|
|
85 |
|
|
86 |
(* ----- axiom and definitions concerning induction ------------------------------- *)
|
|
87 |
|
|
88 |
fun cproj' T = cproj T eqs n;
|
|
89 |
val ax_reach = (dname^"_reach" , mk_trp(cproj'(%%"fix"`%%(comp_dname^"_copy"))
|
1461
|
90 |
`%x_name === %x_name));
|
1274
|
91 |
val ax_take_def = (dname^"_take_def",%%(dname^"_take") == mk_lam("n",
|
1461
|
92 |
cproj'(%%"iterate" $ Bound 0 $ %%(comp_dname^"_copy") $ %%"UU")));
|
1274
|
93 |
val ax_finite_def = (dname^"_finite_def",%%(dname^"_finite") == mk_lam(x_name,
|
1461
|
94 |
mk_ex("n",(%%(dname^"_take") $ Bound 0)`Bound 1 === Bound 1)));
|
1274
|
95 |
|
|
96 |
in [ax_abs_iso, ax_rep_iso, ax_when_def, ax_copy_def] @
|
|
97 |
axs_con_def @ axs_dis_def @ axs_sel_def @
|
|
98 |
[ax_reach, ax_take_def, ax_finite_def] end;
|
|
99 |
|
|
100 |
|
|
101 |
in (* local *)
|
|
102 |
|
|
103 |
fun add_axioms (comp_dname, eqs : eq list) thy' =let
|
|
104 |
val dnames = map (fst o fst) eqs;
|
|
105 |
val x_name = idx_name dnames "x";
|
|
106 |
fun copy_app dname = %%(dname^"_copy")`Bound 0;
|
|
107 |
val ax_copy_def = (comp_dname^"_copy_def" , %%(comp_dname^"_copy") ==
|
1461
|
108 |
/\"f"(foldr' cpair (map copy_app dnames)));
|
1274
|
109 |
val ax_bisim_def = (comp_dname^"_bisim_def",%%(comp_dname^"_bisim") == mk_lam("R",
|
|
110 |
let
|
|
111 |
fun one_con (con,args) = let
|
1461
|
112 |
val nonrec_args = filter_out is_rec args;
|
|
113 |
val rec_args = filter is_rec args;
|
|
114 |
val nonrecs_cnt = length nonrec_args;
|
|
115 |
val recs_cnt = length rec_args;
|
|
116 |
val allargs = nonrec_args @ rec_args
|
|
117 |
@ map (upd_vname (fn s=> s^"'")) rec_args;
|
|
118 |
val allvns = map vname allargs;
|
|
119 |
fun vname_arg s arg = if is_rec arg then vname arg^s else vname arg;
|
|
120 |
val vns1 = map (vname_arg "" ) args;
|
|
121 |
val vns2 = map (vname_arg "'") args;
|
|
122 |
val allargs_cnt = nonrecs_cnt + 2*recs_cnt;
|
|
123 |
val rec_idxs = (recs_cnt-1) downto 0;
|
|
124 |
val nonlazy_idxs = map snd (filter_out (fn (arg,_) => is_lazy arg)
|
|
125 |
(allargs~~((allargs_cnt-1) downto 0)));
|
|
126 |
fun rel_app i ra = proj (Bound(allargs_cnt+2)) dnames (rec_of ra) $
|
|
127 |
Bound (2*recs_cnt-i) $ Bound (recs_cnt-i);
|
|
128 |
val capps = foldr mk_conj (mapn rel_app 1 rec_args,
|
|
129 |
mk_conj(Bound(allargs_cnt+1)===mk_cfapp(%%con,map (bound_arg allvns) vns1),
|
|
130 |
Bound(allargs_cnt+0)===mk_cfapp(%%con,map (bound_arg allvns) vns2)));
|
1274
|
131 |
in foldr mk_ex (allvns, foldr mk_conj
|
1461
|
132 |
(map (defined o Bound) nonlazy_idxs,capps)) end;
|
1274
|
133 |
fun one_comp n (_,cons) = mk_all(x_name (n+1), mk_all(x_name (n+1)^"'", mk_imp(
|
1461
|
134 |
proj (Bound 2) dnames n $ Bound 1 $ Bound 0,
|
1274
|
135 |
foldr' mk_disj (mk_conj(Bound 1 === UU,Bound 0 === UU)::map one_con cons))));
|
|
136 |
in foldr' mk_conj (mapn one_comp 0 eqs)end ));
|
|
137 |
val thy_axs = flat (mapn (calc_axioms comp_dname eqs) 0 eqs) @
|
1461
|
138 |
(if length eqs>1 then [ax_copy_def] else []) @ [ax_bisim_def];
|
1274
|
139 |
in thy' |> add_axioms_i (infer_types thy' thy_axs) end;
|
|
140 |
|
|
141 |
|
|
142 |
fun add_gen_by ((tname,finite),(typs,cnstrs)) thy' = let
|
|
143 |
fun pred_name typ ="P"^(if typs=[typ] then "" else string_of_int(1+find(typ,typs)));
|
|
144 |
fun lift_adm t = lift (fn typ => %%"adm" $ %(pred_name typ))
|
1461
|
145 |
(if finite then [] else typs,t);
|
1274
|
146 |
fun lift_pred_UU t = lift (fn typ => %(pred_name typ) $ UU) (typs,t);
|
|
147 |
fun one_cnstr (cnstr,vns,(args,res)) = let
|
1461
|
148 |
val rec_args = filter (fn (_,typ) => typ mem typs)(vns~~args);
|
|
149 |
val app = mk_cfapp(%%cnstr,map (bound_arg vns) vns);
|
|
150 |
in foldr mk_All (vns,
|
|
151 |
lift (fn (vn,typ) => %(pred_name typ) $ bound_arg vns vn)
|
|
152 |
(rec_args,defined app ==> %(pred_name res)$app)) end;
|
1274
|
153 |
fun one_conc typ = let val pn = pred_name typ in
|
1461
|
154 |
%pn $ %("x"^implode(tl(explode pn))) end;
|
1274
|
155 |
val concl = mk_trp(foldr' mk_conj (map one_conc typs));
|
|
156 |
val induct =(tname^"_induct",lift_adm(lift_pred_UU(
|
1461
|
157 |
foldr (op ===>) (map one_cnstr cnstrs,concl))));
|
1274
|
158 |
in thy' |> add_axioms_i (infer_types thy' [induct]) end;
|
|
159 |
|
|
160 |
end; (* local *)
|
|
161 |
end; (* struct *)
|