1 (* Title: HOLCF/Tools/pcpodef_package.ML |
1 (* Title: HOLCF/Tools/pcpodef_package.ML |
2 ID: $Id$ |
|
3 Author: Brian Huffman |
2 Author: Brian Huffman |
4 |
3 |
5 Primitive domain definitions for HOLCF, similar to Gordon/HOL-style |
4 Primitive domain definitions for HOLCF, similar to Gordon/HOL-style |
6 typedef. |
5 typedef (see also ~~/src/HOL/Tools/typedef_package.ML). |
7 *) |
6 *) |
8 |
7 |
9 signature PCPODEF_PACKAGE = |
8 signature PCPODEF_PACKAGE = |
10 sig |
9 sig |
11 val pcpodef_proof: (bool * string) * (bstring * string list * mixfix) * string |
10 val pcpodef_proof: (bool * string) * (bstring * string list * mixfix) * term |
12 * (string * string) option -> theory -> Proof.state |
11 * (string * string) option -> theory -> Proof.state |
13 val pcpodef_proof_i: (bool * string) * (bstring * string list * mixfix) * term |
12 val pcpodef_proof_cmd: (bool * string) * (bstring * string list * mixfix) * string |
14 * (string * string) option -> theory -> Proof.state |
13 * (string * string) option -> theory -> Proof.state |
15 val cpodef_proof: (bool * string) * (bstring * string list * mixfix) * string |
14 val cpodef_proof: (bool * string) * (bstring * string list * mixfix) * term |
16 * (string * string) option -> theory -> Proof.state |
15 * (string * string) option -> theory -> Proof.state |
17 val cpodef_proof_i: (bool * string) * (bstring * string list * mixfix) * term |
16 val cpodef_proof_cmd: (bool * string) * (bstring * string list * mixfix) * string |
18 * (string * string) option -> theory -> Proof.state |
17 * (string * string) option -> theory -> Proof.state |
19 end; |
18 end; |
20 |
19 |
21 structure PcpodefPackage: PCPODEF_PACKAGE = |
20 structure PcpodefPackage: PCPODEF_PACKAGE = |
22 struct |
21 struct |
23 |
22 |
24 (** theory context references **) |
|
25 |
|
26 val typedef_po = thm "typedef_po"; |
|
27 val typedef_cpo = thm "typedef_cpo"; |
|
28 val typedef_pcpo = thm "typedef_pcpo"; |
|
29 val typedef_lub = thm "typedef_lub"; |
|
30 val typedef_thelub = thm "typedef_thelub"; |
|
31 val typedef_compact = thm "typedef_compact"; |
|
32 val cont_Rep = thm "typedef_cont_Rep"; |
|
33 val cont_Abs = thm "typedef_cont_Abs"; |
|
34 val Rep_strict = thm "typedef_Rep_strict"; |
|
35 val Abs_strict = thm "typedef_Abs_strict"; |
|
36 val Rep_strict_iff = thm "typedef_Rep_strict_iff"; |
|
37 val Abs_strict_iff = thm "typedef_Abs_strict_iff"; |
|
38 val Rep_defined = thm "typedef_Rep_defined"; |
|
39 val Abs_defined = thm "typedef_Abs_defined"; |
|
40 |
|
41 |
|
42 (** type definitions **) |
23 (** type definitions **) |
43 |
24 |
44 (* prepare_cpodef *) |
25 (* prepare_cpodef *) |
45 |
26 |
46 fun err_in_cpodef msg name = |
27 fun err_in_cpodef msg name = |
47 cat_error msg ("The error(s) above occurred in cpodef " ^ quote name); |
28 cat_error msg ("The error(s) above occurred in cpodef " ^ quote name); |
48 |
29 |
49 fun declare_type_name a = Variable.declare_constraints (Logic.mk_type (TFree (a, dummyS))); |
30 fun declare_type_name a = Variable.declare_constraints (Logic.mk_type (TFree (a, dummyS))); |
50 |
31 |
51 fun adm_const T = Const ("Adm.adm", (T --> HOLogic.boolT) --> HOLogic.boolT); |
32 fun adm_const T = Const (@{const_name adm}, (T --> HOLogic.boolT) --> HOLogic.boolT); |
52 fun mk_adm (x, T, P) = adm_const T $ absfree (x, T, P); |
33 fun mk_adm (x, T, P) = adm_const T $ absfree (x, T, P); |
53 |
34 |
54 fun prepare_pcpodef prep_term pcpo def name (t, vs, mx) raw_set opt_morphs thy = |
35 fun prepare_pcpodef prep_term pcpo def name (t, vs, mx) raw_set opt_morphs thy = |
55 let |
36 let |
|
37 val _ = Theory.requires thy "Pcpodef" "pcpodefs"; |
56 val ctxt = ProofContext.init thy; |
38 val ctxt = ProofContext.init thy; |
57 val full = Sign.full_bname thy; |
39 val full = Sign.full_bname thy; |
58 |
40 |
59 (*rhs*) |
41 (*rhs*) |
60 val full_name = full name; |
42 val full_name = full name; |
61 val set = prep_term (ctxt |> fold declare_type_name vs) raw_set; |
43 val set = prep_term (ctxt |> fold declare_type_name vs) raw_set; |
62 val setT = Term.fastype_of set; |
44 val setT = Term.fastype_of set; |
63 val rhs_tfrees = term_tfrees set; |
45 val rhs_tfrees = Term.add_tfrees set []; |
64 val oldT = HOLogic.dest_setT setT handle TYPE _ => |
46 val oldT = HOLogic.dest_setT setT handle TYPE _ => |
65 error ("Not a set type: " ^ quote (Syntax.string_of_typ ctxt setT)); |
47 error ("Not a set type: " ^ quote (Syntax.string_of_typ ctxt setT)); |
66 fun mk_nonempty A = |
48 |
67 HOLogic.mk_exists ("x", oldT, HOLogic.mk_mem (Free ("x", oldT), A)); |
49 (*goal*) |
68 fun mk_admissible A = |
50 val goal_UU_mem = HOLogic.mk_mem (Const (@{const_name UU}, oldT), set); |
69 mk_adm ("x", oldT, HOLogic.mk_mem (Free ("x", oldT), A)); |
51 val goal_nonempty = HOLogic.mk_exists ("x", oldT, HOLogic.mk_mem (Free ("x", oldT), set)); |
70 fun mk_UU_mem A = HOLogic.mk_mem (Const ("Pcpo.UU", oldT), A); |
52 val goal_admissible = mk_adm ("x", oldT, HOLogic.mk_mem (Free ("x", oldT), set)); |
71 val goal = if pcpo |
53 val goal = HOLogic.mk_Trueprop |
72 then HOLogic.mk_Trueprop (HOLogic.mk_conj (mk_UU_mem set, mk_admissible set)) |
54 (HOLogic.mk_conj (if pcpo then goal_UU_mem else goal_nonempty, goal_admissible)); |
73 else HOLogic.mk_Trueprop (HOLogic.mk_conj (mk_nonempty set, mk_admissible set)); |
|
74 |
55 |
75 (*lhs*) |
56 (*lhs*) |
76 val defS = Sign.defaultS thy; |
57 val defS = Sign.defaultS thy; |
77 val lhs_tfrees = map (fn v => (v, the_default defS (AList.lookup (op =) rhs_tfrees v))) vs; |
58 val lhs_tfrees = map (fn v => (v, the_default defS (AList.lookup (op =) rhs_tfrees v))) vs; |
78 val lhs_sorts = map snd lhs_tfrees; |
59 val lhs_sorts = map snd lhs_tfrees; |
|
60 |
79 val tname = Syntax.type_name t mx; |
61 val tname = Syntax.type_name t mx; |
80 val full_tname = full tname; |
62 val full_tname = full tname; |
81 val newT = Type (full_tname, map TFree lhs_tfrees); |
63 val newT = Type (full_tname, map TFree lhs_tfrees); |
82 |
64 |
83 val (Rep_name, Abs_name) = the_default ("Rep_" ^ name, "Abs_" ^ name) opt_morphs; |
65 val (Rep_name, Abs_name) = the_default ("Rep_" ^ name, "Abs_" ^ name) opt_morphs; |
84 val RepC = Const (full Rep_name, newT --> oldT); |
66 val RepC = Const (full Rep_name, newT --> oldT); |
85 fun lessC T = Const (@{const_name Porder.sq_le}, T --> T --> HOLogic.boolT); |
67 fun lessC T = Const (@{const_name sq_le}, T --> T --> HOLogic.boolT); |
86 val less_def = Logic.mk_equals (lessC newT, |
68 val less_def = Logic.mk_equals (lessC newT, |
87 Abs ("x", newT, Abs ("y", newT, lessC oldT $ (RepC $ Bound 1) $ (RepC $ Bound 0)))); |
69 Abs ("x", newT, Abs ("y", newT, lessC oldT $ (RepC $ Bound 1) $ (RepC $ Bound 0)))); |
88 |
70 |
89 fun make_po tac thy1 = |
71 fun make_po tac thy1 = |
90 let |
72 let |
91 val ((_, {type_definition, set_def, ...}), thy2) = thy1 |
73 val ((_, {type_definition, set_def, ...}), thy2) = thy1 |
92 |> TypedefPackage.add_typedef def (SOME name) (t, vs, mx) set opt_morphs tac; |
74 |> TypedefPackage.add_typedef def (SOME name) (t, vs, mx) set opt_morphs tac; |
93 val lthy3 = thy2 |
75 val lthy3 = thy2 |
94 |> TheoryTarget.instantiation ([full_tname], lhs_tfrees, @{sort "Porder.po"}); |
76 |> TheoryTarget.instantiation ([full_tname], lhs_tfrees, @{sort po}); |
95 val less_def' = Syntax.check_term lthy3 less_def; |
77 val less_def' = Syntax.check_term lthy3 less_def; |
96 val ((_, (_, less_definition')), lthy4) = lthy3 |
78 val ((_, (_, less_definition')), lthy4) = lthy3 |
97 |> Specification.definition (NONE, ((Binding.name ("less_" ^ name ^ "_def"), []), less_def')); |
79 |> Specification.definition (NONE, ((Binding.name ("less_" ^ name ^ "_def"), []), less_def')); |
98 val ctxt_thy = ProofContext.init (ProofContext.theory_of lthy4); |
80 val ctxt_thy = ProofContext.init (ProofContext.theory_of lthy4); |
99 val less_definition = singleton (ProofContext.export lthy4 ctxt_thy) less_definition'; |
81 val less_definition = singleton (ProofContext.export lthy4 ctxt_thy) less_definition'; |
100 val thy5 = lthy4 |
82 val thy5 = lthy4 |
101 |> Class.prove_instantiation_instance |
83 |> Class.prove_instantiation_instance |
102 (K (Tactic.rtac (typedef_po OF [type_definition, less_definition]) 1)) |
84 (K (Tactic.rtac (@{thm typedef_po} OF [type_definition, less_definition]) 1)) |
103 |> LocalTheory.exit_global; |
85 |> LocalTheory.exit_global; |
104 in ((type_definition, less_definition, set_def), thy5) end; |
86 in ((type_definition, less_definition, set_def), thy5) end; |
105 |
87 |
106 fun make_cpo admissible (type_def, less_def, set_def) theory = |
88 fun make_cpo admissible (type_def, less_def, set_def) theory = |
107 let |
89 let |
108 val admissible' = fold_rule (the_list set_def) admissible; |
90 val admissible' = fold_rule (the_list set_def) admissible; |
109 val cpo_thms = map (Thm.transfer theory) [type_def, less_def, admissible']; |
91 val cpo_thms = map (Thm.transfer theory) [type_def, less_def, admissible']; |
110 val theory' = theory |
92 val theory' = theory |
111 |> AxClass.prove_arity (full_tname, lhs_sorts, ["Pcpo.cpo"]) |
93 |> AxClass.prove_arity (full_tname, lhs_sorts, @{sort cpo}) |
112 (Tactic.rtac (typedef_cpo OF cpo_thms) 1); |
94 (Tactic.rtac (@{thm typedef_cpo} OF cpo_thms) 1); |
113 val cpo_thms' = map (Thm.transfer theory') cpo_thms; |
95 val cpo_thms' = map (Thm.transfer theory') cpo_thms; |
114 in |
96 in |
115 theory' |
97 theory' |
116 |> Sign.add_path name |
98 |> Sign.add_path name |
117 |> PureThy.add_thms |
99 |> PureThy.add_thms |
118 ([(("adm_" ^ name, admissible'), []), |
100 ([(("adm_" ^ name, admissible'), []), |
119 (("cont_" ^ Rep_name, cont_Rep OF cpo_thms'), []), |
101 (("cont_" ^ Rep_name, @{thm typedef_cont_Rep} OF cpo_thms'), []), |
120 (("cont_" ^ Abs_name, cont_Abs OF cpo_thms'), []), |
102 (("cont_" ^ Abs_name, @{thm typedef_cont_Abs} OF cpo_thms'), []), |
121 (("lub_" ^ name, typedef_lub OF cpo_thms'), []), |
103 (("lub_" ^ name, @{thm typedef_lub} OF cpo_thms'), []), |
122 (("thelub_" ^ name, typedef_thelub OF cpo_thms'), []), |
104 (("thelub_" ^ name, @{thm typedef_thelub} OF cpo_thms'), []), |
123 (("compact_" ^ name, typedef_compact OF cpo_thms'), [])]) |
105 (("compact_" ^ name, @{thm typedef_compact} OF cpo_thms'), [])]) |
124 |> snd |
106 |> snd |
125 |> Sign.parent_path |
107 |> Sign.parent_path |
126 end; |
108 end; |
127 |
109 |
128 fun make_pcpo UUmem (type_def, less_def, set_def) theory = |
110 fun make_pcpo UUmem (type_def, less_def, set_def) theory = |
129 let |
111 let |
130 val UUmem' = fold_rule (the_list set_def) UUmem; |
112 val UUmem' = fold_rule (the_list set_def) UUmem; |
131 val pcpo_thms = map (Thm.transfer theory) [type_def, less_def, UUmem']; |
113 val pcpo_thms = map (Thm.transfer theory) [type_def, less_def, UUmem']; |
132 val theory' = theory |
114 val theory' = theory |
133 |> AxClass.prove_arity (full_tname, lhs_sorts, ["Pcpo.pcpo"]) |
115 |> AxClass.prove_arity (full_tname, lhs_sorts, @{sort pcpo}) |
134 (Tactic.rtac (typedef_pcpo OF pcpo_thms) 1); |
116 (Tactic.rtac (@{thm typedef_pcpo} OF pcpo_thms) 1); |
135 val pcpo_thms' = map (Thm.transfer theory') pcpo_thms; |
117 val pcpo_thms' = map (Thm.transfer theory') pcpo_thms; |
136 in |
118 in |
137 theory' |
119 theory' |
138 |> Sign.add_path name |
120 |> Sign.add_path name |
139 |> PureThy.add_thms |
121 |> PureThy.add_thms |
140 ([((Rep_name ^ "_strict", Rep_strict OF pcpo_thms'), []), |
122 ([((Rep_name ^ "_strict", @{thm typedef_Rep_strict} OF pcpo_thms'), []), |
141 ((Abs_name ^ "_strict", Abs_strict OF pcpo_thms'), []), |
123 ((Abs_name ^ "_strict", @{thm typedef_Abs_strict} OF pcpo_thms'), []), |
142 ((Rep_name ^ "_strict_iff", Rep_strict_iff OF pcpo_thms'), []), |
124 ((Rep_name ^ "_strict_iff", @{thm typedef_Rep_strict_iff} OF pcpo_thms'), []), |
143 ((Abs_name ^ "_strict_iff", Abs_strict_iff OF pcpo_thms'), []), |
125 ((Abs_name ^ "_strict_iff", @{thm typedef_Abs_strict_iff} OF pcpo_thms'), []), |
144 ((Rep_name ^ "_defined", Rep_defined OF pcpo_thms'), []), |
126 ((Rep_name ^ "_defined", @{thm typedef_Rep_defined} OF pcpo_thms'), []), |
145 ((Abs_name ^ "_defined", Abs_defined OF pcpo_thms'), []) |
127 ((Abs_name ^ "_defined", @{thm typedef_Abs_defined} OF pcpo_thms'), []) |
146 ]) |
128 ]) |
147 |> snd |
129 |> snd |
148 |> Sign.parent_path |
130 |> Sign.parent_path |
149 end; |
131 end; |
150 |
132 |
170 |
152 |
171 in (goal, if pcpo then pcpodef_result else cpodef_result) end |
153 in (goal, if pcpo then pcpodef_result else cpodef_result) end |
172 handle ERROR msg => err_in_cpodef msg name; |
154 handle ERROR msg => err_in_cpodef msg name; |
173 |
155 |
174 |
156 |
175 (* cpodef_proof interface *) |
157 (* proof interface *) |
|
158 |
|
159 local |
176 |
160 |
177 fun gen_pcpodef_proof prep_term pcpo ((def, name), typ, set, opt_morphs) thy = |
161 fun gen_pcpodef_proof prep_term pcpo ((def, name), typ, set, opt_morphs) thy = |
178 let |
162 let |
179 val (goal, pcpodef_result) = |
163 val (goal, pcpodef_result) = |
180 prepare_pcpodef prep_term pcpo def name typ set opt_morphs thy; |
164 prepare_pcpodef prep_term pcpo def name typ set opt_morphs thy; |
181 fun after_qed [[th]] = ProofContext.theory (pcpodef_result th); |
165 fun after_qed [[th]] = ProofContext.theory (pcpodef_result th); |
182 in Proof.theorem_i NONE after_qed [[(goal, [])]] (ProofContext.init thy) end; |
166 in Proof.theorem_i NONE after_qed [[(goal, [])]] (ProofContext.init thy) end; |
183 |
167 |
184 fun pcpodef_proof x = gen_pcpodef_proof Syntax.read_term true x; |
168 in |
185 fun pcpodef_proof_i x = gen_pcpodef_proof Syntax.check_term true x; |
169 |
186 |
170 fun pcpodef_proof x = gen_pcpodef_proof Syntax.check_term true x; |
187 fun cpodef_proof x = gen_pcpodef_proof Syntax.read_term false x; |
171 fun pcpodef_proof_cmd x = gen_pcpodef_proof Syntax.read_term true x; |
188 fun cpodef_proof_i x = gen_pcpodef_proof Syntax.check_term false x; |
172 |
|
173 fun cpodef_proof x = gen_pcpodef_proof Syntax.check_term false x; |
|
174 fun cpodef_proof_cmd x = gen_pcpodef_proof Syntax.read_term false x; |
|
175 |
|
176 end; |
|
177 |
189 |
178 |
190 |
179 |
191 (** outer syntax **) |
180 (** outer syntax **) |
192 |
181 |
193 local structure P = OuterParse and K = OuterKeyword in |
182 local structure P = OuterParse and K = OuterKeyword in |
194 |
183 |
195 (* cf. HOL/Tools/typedef_package.ML *) |
|
196 val typedef_proof_decl = |
184 val typedef_proof_decl = |
197 Scan.optional (P.$$$ "(" |-- |
185 Scan.optional (P.$$$ "(" |-- |
198 ((P.$$$ "open" >> K false) -- Scan.option P.name || P.name >> (fn s => (true, SOME s))) |
186 ((P.$$$ "open" >> K false) -- Scan.option P.name || P.name >> (fn s => (true, SOME s))) |
199 --| P.$$$ ")") (true, NONE) -- |
187 --| P.$$$ ")") (true, NONE) -- |
200 (P.type_args -- P.name) -- P.opt_infix -- (P.$$$ "=" |-- P.term) -- |
188 (P.type_args -- P.name) -- P.opt_infix -- (P.$$$ "=" |-- P.term) -- |
201 Scan.option (P.$$$ "morphisms" |-- P.!!! (P.name -- P.name)); |
189 Scan.option (P.$$$ "morphisms" |-- P.!!! (P.name -- P.name)); |
202 |
190 |
203 fun mk_pcpodef_proof pcpo ((((((def, opt_name), (vs, t)), mx), A), morphs)) = |
191 fun mk_pcpodef_proof pcpo ((((((def, opt_name), (vs, t)), mx), A), morphs)) = |
204 (if pcpo then pcpodef_proof else cpodef_proof) |
192 (if pcpo then pcpodef_proof_cmd else cpodef_proof_cmd) |
205 ((def, the_default (Syntax.type_name t mx) opt_name), (t, vs, mx), A, morphs); |
193 ((def, the_default (Syntax.type_name t mx) opt_name), (t, vs, mx), A, morphs); |
206 |
194 |
207 val _ = |
195 val _ = |
208 OuterSyntax.command "pcpodef" "HOLCF type definition (requires admissibility proof)" K.thy_goal |
196 OuterSyntax.command "pcpodef" "HOLCF type definition (requires admissibility proof)" K.thy_goal |
209 (typedef_proof_decl >> |
197 (typedef_proof_decl >> |