69 following "case" and the asterisk after esac will be deleted *) |
69 following "case" and the asterisk after esac will be deleted *) |
70 |
70 |
71 oracle mc_mucke_oracle ("term") = |
71 oracle mc_mucke_oracle ("term") = |
72 mk_mc_mucke_oracle |
72 mk_mc_mucke_oracle |
73 |
73 |
|
74 ML {* |
|
75 (* search_mu t searches for Mu terms in term t. In the case of nested Mu's, |
|
76 it yields innermost one. If no Mu term is present, search_mu yields NONE |
|
77 *) |
|
78 |
|
79 (* extended for treatment of nu (TH) *) |
|
80 fun search_mu ((Const("MuCalculus.mu",tp)) $ t2) = |
|
81 (case (search_mu t2) of |
|
82 SOME t => SOME t |
|
83 | NONE => SOME ((Const("MuCalculus.mu",tp)) $ t2)) |
|
84 | search_mu ((Const("MuCalculus.nu",tp)) $ t2) = |
|
85 (case (search_mu t2) of |
|
86 SOME t => SOME t |
|
87 | NONE => SOME ((Const("MuCalculus.nu",tp)) $ t2)) |
|
88 | search_mu (t1 $ t2) = |
|
89 (case (search_mu t1) of |
|
90 SOME t => SOME t |
|
91 | NONE => search_mu t2) |
|
92 | search_mu (Abs(_,_,t)) = search_mu t |
|
93 | search_mu _ = NONE; |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 (* seraching a variable in a term. Used in move_mus to extract the |
|
99 term-rep of var b in hthm *) |
|
100 |
|
101 fun search_var s t = |
|
102 case t of |
|
103 t1 $ t2 => (case (search_var s t1) of |
|
104 SOME tt => SOME tt | |
|
105 NONE => search_var s t2) | |
|
106 Abs(_,_,t) => search_var s t | |
|
107 Var((s1,_),_) => if s = s1 then SOME t else NONE | |
|
108 _ => NONE; |
|
109 |
|
110 |
|
111 (* function move_mus: |
|
112 Mucke can't deal with nested Mu terms. move_mus i searches for |
|
113 Mu terms in the subgoal i and replaces Mu terms in the conclusion |
|
114 by constants and definitions in the premises recursively. |
|
115 |
|
116 move_thm is the theorem the performs the replacement. To create NEW |
|
117 names for the Mu terms, the indizes of move_thm are incremented by |
|
118 max_idx of the subgoal. |
|
119 *) |
|
120 |
|
121 local |
|
122 |
|
123 val move_thm = prove_goal (the_context ()) "[| a = b ==> P a; a = b |] ==> P b" |
|
124 (fn prems => [cut_facts_tac prems 1, dtac sym 1, hyp_subst_tac 1, |
|
125 REPEAT (resolve_tac prems 1)]); |
|
126 |
|
127 val sig_move_thm = Thm.theory_of_thm move_thm; |
|
128 val bCterm = cterm_of sig_move_thm (valOf (search_var "b" (concl_of move_thm))); |
|
129 val aCterm = cterm_of sig_move_thm (valOf (search_var "a" (hd(prems_of move_thm)))); |
|
130 |
|
131 in |
|
132 |
|
133 fun move_mus i state = |
|
134 let val sign = Thm.theory_of_thm state; |
|
135 val (subgoal::_) = Library.drop(i-1,prems_of state); |
|
136 val concl = Logic.strip_imp_concl subgoal; (* recursive mu's in prems? *) |
|
137 val redex = search_mu concl; |
|
138 val idx = let val t = #maxidx (rep_thm state) in |
|
139 if t < 0 then 1 else t+1 end; |
|
140 in |
|
141 case redex of |
|
142 NONE => all_tac state | |
|
143 SOME redexterm => |
|
144 let val Credex = cterm_of sign redexterm; |
|
145 val aiCterm = |
|
146 cterm_of sig_move_thm (Logic.incr_indexes ([],idx) (term_of aCterm)); |
|
147 val inst_move_thm = cterm_instantiate |
|
148 [(bCterm,Credex),(aCterm,aiCterm)] move_thm; |
|
149 in |
|
150 ((rtac inst_move_thm i) THEN (dtac eq_reflection i) |
|
151 THEN (move_mus i)) state |
|
152 end |
|
153 end; |
|
154 end; |
|
155 |
|
156 |
|
157 fun call_mucke_tac i state = |
|
158 let val thy = Thm.theory_of_thm state; |
|
159 val OraAss = mc_mucke_oracle thy (Logic.nth_prem (i, Thm.prop_of state)) |
|
160 in |
|
161 (cut_facts_tac [OraAss] i) state |
|
162 end; |
|
163 |
|
164 |
|
165 (* transforming fun-defs into lambda-defs *) |
|
166 |
|
167 val [eq] = goal CPure.thy "(!! x. f x == g x) ==> f == g"; |
|
168 by (rtac (extensional eq) 1); |
|
169 qed "ext_rl"; |
|
170 |
|
171 infix cc; |
|
172 |
|
173 fun NONE cc xl = xl |
|
174 | (SOME x) cc xl = x::xl; |
|
175 |
|
176 fun getargs ((x $ y) $ (Var ((z,_),_))) = getargs (x $ y) ^ " " ^z |
|
177 | getargs (x $ (Var ((y,_),_))) = y; |
|
178 |
|
179 fun getfun ((x $ y) $ z) = getfun (x $ y) |
|
180 | getfun (x $ _) = x; |
|
181 |
|
182 local |
|
183 |
|
184 fun delete_bold [] = [] |
|
185 | delete_bold (x::xs) = if (is_prefix (op =) ("\^["::"["::"0"::"m"::[]) (x::xs)) |
|
186 then (let val (_::_::_::s) = xs in delete_bold s end) |
|
187 else (if (is_prefix (op =) ("\^["::"["::"1"::"m"::[]) (x::xs)) |
|
188 then (let val (_::_::_::s) = xs in delete_bold s end) |
|
189 else (x::delete_bold xs)); |
|
190 |
|
191 fun delete_bold_string s = implode(delete_bold (explode s)); |
|
192 |
|
193 in |
|
194 |
|
195 (* extension with removing bold font (TH) *) |
|
196 fun mk_lam_def (_::_) _ _ = NONE |
|
197 | mk_lam_def [] ((Const("==",_) $ (Const _)) $ RHS) t = SOME t |
|
198 | mk_lam_def [] ((Const("==",_) $ LHS) $ RHS) t = |
|
199 let val thy = theory_of_thm t; |
|
200 val fnam = Sign.string_of_term thy (getfun LHS); |
|
201 val rhs = Sign.string_of_term thy (freeze_thaw RHS) |
|
202 val gl = delete_bold_string (fnam ^" == % " ^ (getargs LHS) ^" . " ^ rhs); |
|
203 in |
|
204 SOME (prove_goal thy gl (fn prems => |
|
205 [(REPEAT (rtac ext_rl 1)), (rtac t 1) ])) |
|
206 end |
|
207 | mk_lam_def [] _ t= NONE; |
|
208 |
|
209 fun mk_lam_defs ([]:thm list) = ([]: thm list) |
|
210 | mk_lam_defs (t::l) = |
|
211 (mk_lam_def (prems_of t) (concl_of t) t) cc (mk_lam_defs l); |
|
212 |
|
213 end; |
|
214 |
|
215 |
|
216 (* first simplification, then model checking *) |
|
217 |
|
218 val pair_eta_expand = Thm.symmetric (mk_meta_eq (thm "split_eta")); |
|
219 |
|
220 val pair_eta_expand_proc = |
|
221 Simplifier.simproc (the_context ()) "pair_eta_expand" ["f::'a*'b=>'c"] |
|
222 (fn _ => fn _ => fn t => case t of Abs _ => SOME pair_eta_expand | _ => NONE); |
|
223 |
|
224 val Mucke_ss = simpset() addsimprocs [pair_eta_expand_proc] addsimps [Let_def]; |
|
225 |
|
226 |
|
227 (* the interface *) |
|
228 |
|
229 fun mc_mucke_tac defs i state = |
|
230 (case Library.drop (i - 1, Thm.prems_of state) of |
|
231 [] => no_tac state |
|
232 | subgoal :: _ => |
|
233 EVERY [ |
|
234 REPEAT (etac thin_rl i), |
|
235 cut_facts_tac (mk_lam_defs defs) i, |
|
236 full_simp_tac (Mucke_ss delsimps [not_iff,split_part]) i, |
|
237 move_mus i, call_mucke_tac i,atac i, |
|
238 REPEAT (rtac refl i)] state); |
|
239 |
|
240 (*check if user has mucke installed*) |
|
241 fun mucke_enabled () = getenv "MUCKE_HOME" <> ""; |
|
242 fun if_mucke_enabled f x = if mucke_enabled () then f x else (); |
|
243 |
|
244 *} |
|
245 |
74 end |
246 end |
75 |
|
76 |
|