2 ID: $Id$ |
2 ID: $Id$ |
3 Author: Alexander Krauss, TU Muenchen |
3 Author: Alexander Krauss, TU Muenchen |
4 |
4 |
5 Tactics for size change termination. |
5 Tactics for size change termination. |
6 *) |
6 *) |
7 signature SCT = |
7 signature SCT = |
8 sig |
8 sig |
9 val abs_rel_tac : tactic |
9 val abs_rel_tac : tactic |
10 val mk_call_graph : tactic |
10 val mk_call_graph : tactic |
11 end |
11 end |
12 |
12 |
13 structure Sct : SCT = |
13 structure Sct : SCT = |
14 struct |
14 struct |
15 |
15 |
16 fun matrix [] ys = [] |
16 fun matrix [] ys = [] |
17 | matrix (x::xs) ys = map (pair x) ys :: matrix xs ys |
17 | matrix (x::xs) ys = map (pair x) ys :: matrix xs ys |
18 |
18 |
19 fun map_matrix f xss = map (map f) xss |
19 fun map_matrix f xss = map (map f) xss |
20 |
20 |
21 val scgT = Sign.read_typ (the_context (), K NONE) "scg" |
21 val scgT = @{typ scg} |
22 val acgT = Sign.read_typ (the_context (), K NONE) "acg" |
22 val acgT = @{typ acg} |
23 |
23 |
24 fun edgeT nT eT = HOLogic.mk_prodT (nT, HOLogic.mk_prodT (eT, nT)) |
24 fun edgeT nT eT = HOLogic.mk_prodT (nT, HOLogic.mk_prodT (eT, nT)) |
25 fun graphT nT eT = Type ("Graphs.graph", [nT, eT]) |
25 fun graphT nT eT = Type ("Graphs.graph", [nT, eT]) |
26 |
26 |
27 fun graph_const nT eT = Const ("Graphs.graph.Graph", HOLogic.mk_setT (edgeT nT eT) --> graphT nT eT) |
27 fun graph_const nT eT = Const ("Graphs.graph.Graph", HOLogic.mk_setT (edgeT nT eT) --> graphT nT eT) |
28 |
28 |
29 val stepP_const = "SCT_Interpretation.stepP" |
29 val stepP_const = "SCT_Interpretation.stepP" |
30 val stepP_def = thm "SCT_Interpretation.stepP.simps" |
30 val stepP_def = thm "SCT_Interpretation.stepP.simps" |
31 |
31 |
32 fun mk_stepP RD1 RD2 M1 M2 Rel = |
32 fun mk_stepP RD1 RD2 M1 M2 Rel = |
33 let val RDT = fastype_of RD1 |
33 let val RDT = fastype_of RD1 |
34 val MT = fastype_of M1 |
34 val MT = fastype_of M1 |
35 in |
35 in |
36 Const (stepP_const, RDT --> RDT --> MT --> MT --> (fastype_of Rel) --> HOLogic.boolT) |
36 Const (stepP_const, RDT --> RDT --> MT --> MT --> (fastype_of Rel) --> HOLogic.boolT) |
37 $ RD1 $ RD2 $ M1 $ M2 $ Rel |
37 $ RD1 $ RD2 $ M1 $ M2 $ Rel |
38 end |
38 end |
39 |
39 |
40 val no_stepI = thm "SCT_Interpretation.no_stepI" |
40 val no_stepI = thm "SCT_Interpretation.no_stepI" |
41 |
41 |
42 val approx_const = "SCT_Interpretation.approx" |
42 val approx_const = "SCT_Interpretation.approx" |
43 val approx_empty = thm "SCT_Interpretation.approx_empty" |
43 val approx_empty = thm "SCT_Interpretation.approx_empty" |
44 val approx_less = thm "SCT_Interpretation.approx_less" |
44 val approx_less = thm "SCT_Interpretation.approx_less" |
45 val approx_leq = thm "SCT_Interpretation.approx_leq" |
45 val approx_leq = thm "SCT_Interpretation.approx_leq" |
46 |
46 |
47 fun mk_approx G RD1 RD2 Ms1 Ms2 = |
47 fun mk_approx G RD1 RD2 Ms1 Ms2 = |
48 let val RDT = fastype_of RD1 |
48 let val RDT = fastype_of RD1 |
49 val MsT = fastype_of Ms1 |
49 val MsT = fastype_of Ms1 |
50 in Const (approx_const, scgT --> RDT --> RDT --> MsT --> MsT --> HOLogic.boolT) $ G $ RD1 $ RD2 $ Ms1 $ Ms2 end |
50 in Const (approx_const, scgT --> RDT --> RDT --> MsT --> MsT --> HOLogic.boolT) $ G $ RD1 $ RD2 $ Ms1 $ Ms2 end |
51 |
51 |
52 val sound_int_const = "SCT_Interpretation.sound_int" |
52 val sound_int_const = "SCT_Interpretation.sound_int" |
72 val all_less_Suc = thm "SCT_Interpretation.all_less_Suc" |
72 val all_less_Suc = thm "SCT_Interpretation.all_less_Suc" |
73 |
73 |
74 (* --> Library? *) |
74 (* --> Library? *) |
75 fun del_index n [] = [] |
75 fun del_index n [] = [] |
76 | del_index n (x :: xs) = |
76 | del_index n (x :: xs) = |
77 if n>0 then x :: del_index (n - 1) xs else xs |
77 if n>0 then x :: del_index (n - 1) xs else xs |
78 |
78 |
79 (* Lists as finite multisets *) |
79 (* Lists as finite multisets *) |
80 |
80 |
81 fun remove1 eq x [] = [] |
81 fun remove1 eq x [] = [] |
82 | remove1 eq x (y :: ys) = if eq (x, y) then ys else y :: remove1 eq x ys |
82 | remove1 eq x (y :: ys) = if eq (x, y) then ys else y :: remove1 eq x ys |
89 val (n, body) = Term.dest_abs a |
89 val (n, body) = Term.dest_abs a |
90 in |
90 in |
91 (Free (n, T), body) |
91 (Free (n, T), body) |
92 end |
92 end |
93 | dest_ex _ = raise Match |
93 | dest_ex _ = raise Match |
94 |
94 |
95 fun dest_all_ex (t as (Const ("Ex",_) $ _)) = |
95 fun dest_all_ex (t as (Const ("Ex",_) $ _)) = |
96 let |
96 let |
97 val (v,b) = dest_ex t |
97 val (v,b) = dest_ex t |
98 val (vs, b') = dest_all_ex b |
98 val (vs, b') = dest_all_ex b |
99 in |
99 in |
100 (v :: vs, b') |
100 (v :: vs, b') |
101 end |
101 end |
102 | dest_all_ex t = ([],t) |
102 | dest_all_ex t = ([],t) |
103 |
103 |
104 fun dist_vars [] vs = (null vs orelse error "dist_vars"; []) |
104 fun dist_vars [] vs = (null vs orelse error "dist_vars"; []) |
105 | dist_vars (T::Ts) vs = |
105 | dist_vars (T::Ts) vs = |
106 case find_index (fn v => fastype_of v = T) vs of |
106 case find_index (fn v => fastype_of v = T) vs of |
107 ~1 => Free ("", T) :: dist_vars Ts vs |
107 ~1 => Free ("", T) :: dist_vars Ts vs |
108 | i => (nth vs i) :: dist_vars Ts (del_index i vs) |
108 | i => (nth vs i) :: dist_vars Ts (del_index i vs) |
109 |
109 |
110 fun dest_case rebind t = |
110 fun dest_case rebind t = |
111 let |
111 let |
112 val (_ $ _ $ rhs :: _ $ _ $ match :: guards) = HOLogic.dest_conj t |
112 val (_ $ _ $ rhs :: _ $ _ $ match :: guards) = HOLogic.dest_conj t |
113 val guard = case guards of [] => HOLogic.true_const | gs => foldr1 HOLogic.mk_conj gs |
113 val guard = case guards of [] => HOLogic.true_const | gs => foldr1 HOLogic.mk_conj gs |
114 in |
114 in |
115 foldr1 HOLogic.mk_prod [rebind guard, rebind rhs, rebind match] |
115 foldr1 HOLogic.mk_prod [rebind guard, rebind rhs, rebind match] |
116 end |
116 end |
117 |
117 |
118 fun bind_many [] = I |
118 fun bind_many [] = I |
119 | bind_many vs = FundefLib.tupled_lambda (foldr1 HOLogic.mk_prod vs) |
119 | bind_many vs = FundefLib.tupled_lambda (foldr1 HOLogic.mk_prod vs) |
120 |
120 |
121 (* Builds relation descriptions from a relation definition *) |
121 (* Builds relation descriptions from a relation definition *) |
122 fun mk_reldescs (Abs a) = |
122 fun mk_reldescs (Abs a) = |
123 let |
123 let |
124 val (_, Abs a') = Term.dest_abs a |
124 val (_, Abs a') = Term.dest_abs a |
125 val (_, b) = Term.dest_abs a' |
125 val (_, b) = Term.dest_abs a' |
126 val cases = HOLogic.dest_disj b |
126 val cases = HOLogic.dest_disj b |
127 val (vss, bs) = split_list (map dest_all_ex cases) |
127 val (vss, bs) = split_list (map dest_all_ex cases) |
128 val unionTs = fold (multi_union (op =)) (map (map fastype_of) vss) [] |
128 val unionTs = fold (multi_union (op =)) (map (map fastype_of) vss) [] |
129 val rebind = map (bind_many o dist_vars unionTs) vss |
129 val rebind = map (bind_many o dist_vars unionTs) vss |
130 |
130 |
131 val RDs = map2 dest_case rebind bs |
131 val RDs = map2 dest_case rebind bs |
132 in |
132 in |
133 HOLogic.mk_list (fastype_of (hd RDs)) RDs |
133 HOLogic.mk_list (fastype_of (hd RDs)) RDs |
134 end |
134 end |
135 |
135 |
175 the o Inttab.lookup table |
175 the o Inttab.lookup table |
176 end |
176 end |
177 |
177 |
178 val get_elem = snd o Logic.dest_equals o prop_of |
178 val get_elem = snd o Logic.dest_equals o prop_of |
179 |
179 |
180 fun inst_nums thy i j (t:thm) = |
180 fun inst_nums thy i j (t:thm) = |
181 instantiate' [] [NONE, NONE, NONE, SOME (cterm_of thy (mk_number i)), NONE, SOME (cterm_of thy (mk_number j))] t |
181 instantiate' [] [NONE, NONE, NONE, SOME (cterm_of thy (mk_number i)), NONE, SOME (cterm_of thy (mk_number j))] t |
182 |
182 |
183 datatype call_fact = |
183 datatype call_fact = |
184 NoStep of thm |
184 NoStep of thm |
185 | Graph of (term * thm) |
185 | Graph of (term * thm) |
202 val N = length Mst1 and M = length Mst2 |
202 val N = length Mst1 and M = length Mst2 |
203 val saved_state = HOLogic.mk_Trueprop (mk_stepP RD1 RD2 mvar1 mvar2 relvar) |
203 val saved_state = HOLogic.mk_Trueprop (mk_stepP RD1 RD2 mvar1 mvar2 relvar) |
204 |> cterm_of thy |
204 |> cterm_of thy |
205 |> Goal.init |
205 |> Goal.init |
206 |> CLASIMPSET auto_tac |> Seq.hd |
206 |> CLASIMPSET auto_tac |> Seq.hd |
207 |
207 |
208 val no_step = saved_state |
208 val no_step = saved_state |
209 |> forall_intr (cterm_of thy relvar) |
209 |> forall_intr (cterm_of thy relvar) |
210 |> forall_elim (cterm_of thy (Abs ("", HOLogic.natT, Abs ("", HOLogic.natT, HOLogic.false_const)))) |
210 |> forall_elim (cterm_of thy (Abs ("", HOLogic.natT, Abs ("", HOLogic.natT, HOLogic.false_const)))) |
211 |> CLASIMPSET auto_tac |> Seq.hd |
211 |> CLASIMPSET auto_tac |> Seq.hd |
212 |
212 |
213 in |
213 in |
214 if Thm.no_prems no_step |
214 if Thm.no_prems no_step |
215 then NoStep (Goal.finish no_step RS no_stepI) |
215 then NoStep (Goal.finish no_step RS no_stepI) |
216 else |
216 else |
217 let |
217 let |
218 fun set_m1 i = |
218 fun set_m1 i = |
219 let |
219 let |
220 val M1 = nth Mst1 i |
220 val M1 = nth Mst1 i |
221 val with_m1 = saved_state |
221 val with_m1 = saved_state |
222 |> forall_intr (cterm_of thy mvar1) |
222 |> forall_intr (cterm_of thy mvar1) |
223 |> forall_elim (cterm_of thy M1) |
223 |> forall_elim (cterm_of thy M1) |
224 |> CLASIMPSET auto_tac |> Seq.hd |
224 |> CLASIMPSET auto_tac |> Seq.hd |
225 |
225 |
226 fun set_m2 j = |
226 fun set_m2 j = |
227 let |
227 let |
228 val M2 = nth Mst2 j |
228 val M2 = nth Mst2 j |
229 val with_m2 = with_m1 |
229 val with_m2 = with_m1 |
230 |> forall_intr (cterm_of thy mvar2) |
230 |> forall_intr (cterm_of thy mvar2) |
231 |> forall_elim (cterm_of thy M2) |
231 |> forall_elim (cterm_of thy M2) |
232 |> CLASIMPSET auto_tac |> Seq.hd |
232 |> CLASIMPSET auto_tac |> Seq.hd |
239 #> forall_elim (cterm_of thy lesseq_nat_const) |
239 #> forall_elim (cterm_of thy lesseq_nat_const) |
240 #> CLASIMPSET auto_tac #> Seq.hd |
240 #> CLASIMPSET auto_tac #> Seq.hd |
241 |
241 |
242 val thm1 = decr with_m2 |
242 val thm1 = decr with_m2 |
243 in |
243 in |
244 if Thm.no_prems thm1 |
244 if Thm.no_prems thm1 |
245 then ((rtac (inst_nums thy i j approx_less) 1) THEN (simp_nth_tac 1) THEN (rtac (Goal.finish thm1) 1)) |
245 then ((rtac (inst_nums thy i j approx_less) 1) THEN (simp_nth_tac 1) THEN (rtac (Goal.finish thm1) 1)) |
246 else let val thm2 = decreq with_m2 in |
246 else let val thm2 = decreq with_m2 in |
247 if Thm.no_prems thm2 |
247 if Thm.no_prems thm2 |
248 then ((rtac (inst_nums thy i j approx_leq) 1) THEN (simp_nth_tac 1) THEN (rtac (Goal.finish thm2) 1)) |
248 then ((rtac (inst_nums thy i j approx_leq) 1) THEN (simp_nth_tac 1) THEN (rtac (Goal.finish thm2) 1)) |
249 else all_tac end |
249 else all_tac end |
250 end |
250 end |
251 in set_m2 end |
251 in set_m2 end |
252 |
252 |
253 val goal = HOLogic.mk_Trueprop (mk_approx (Var (("G", 0), scgT)) RD1 RD2 Ms1 Ms2) |
253 val goal = HOLogic.mk_Trueprop (mk_approx (Var (("G", 0), scgT)) RD1 RD2 Ms1 Ms2) |
254 |
254 |
255 val tac = (EVERY (map (fn n => EVERY (map (set_m1 n) (0 upto M - 1))) (0 upto N - 1))) |
255 val tac = (EVERY (map (fn n => EVERY (map (set_m1 n) (0 upto M - 1))) (0 upto N - 1))) |
256 THEN (rtac approx_empty 1) |
256 THEN (rtac approx_empty 1) |
257 |
257 |
258 val approx_thm = goal |
258 val approx_thm = goal |
259 |> cterm_of thy |
259 |> cterm_of thy |
260 |> Goal.init |
260 |> Goal.init |
261 |> tac |> Seq.hd |
261 |> tac |> Seq.hd |
262 |> Goal.finish |
262 |> Goal.finish |
263 |
263 |
277 | dest_set (Const ("insert", _) $ x $ xs) = x :: dest_set xs |
277 | dest_set (Const ("insert", _) $ x $ xs) = x :: dest_set xs |
278 |
278 |
279 val pr_graph = Sign.string_of_term |
279 val pr_graph = Sign.string_of_term |
280 fun pr_matrix thy = map_matrix (fn Graph (G, _) => pr_graph thy G | _ => "X") |
280 fun pr_matrix thy = map_matrix (fn Graph (G, _) => pr_graph thy G | _ => "X") |
281 |
281 |
282 val in_graph_tac = |
282 val in_graph_tac = |
283 simp_tac (HOL_basic_ss addsimps has_edge_simps) 1 |
283 simp_tac (HOL_basic_ss addsimps has_edge_simps) 1 |
284 THEN SIMPSET (fn x => simp_tac x 1) (* FIXME reduce simpset *) |
284 THEN SIMPSET (fn x => simp_tac x 1) (* FIXME reduce simpset *) |
285 |
285 |
286 fun approx_tac (NoStep thm) = rtac disjI1 1 THEN rtac thm 1 |
286 fun approx_tac (NoStep thm) = rtac disjI1 1 THEN rtac thm 1 |
287 | approx_tac (Graph (G, thm)) = |
287 | approx_tac (Graph (G, thm)) = |
288 rtac disjI2 1 |
288 rtac disjI2 1 |
289 THEN rtac exI 1 |
289 THEN rtac exI 1 |
290 THEN rtac conjI 1 |
290 THEN rtac conjI 1 |
291 THEN rtac thm 2 |
291 THEN rtac thm 2 |
292 THEN in_graph_tac |
292 THEN in_graph_tac |
293 |
293 |
294 fun all_less_tac [] = rtac all_less_zero 1 |
294 fun all_less_tac [] = rtac all_less_zero 1 |
295 | all_less_tac (t :: ts) = rtac all_less_Suc 1 |
295 | all_less_tac (t :: ts) = rtac all_less_Suc 1 |
296 THEN simp_nth_tac 1 |
296 THEN simp_nth_tac 1 |
297 THEN t |
297 THEN t |
298 THEN all_less_tac ts |
298 THEN all_less_tac ts |
299 |
299 |
300 |
300 |
301 val length_const = "Nat.size" |
301 val length_const = "Nat.size" |
302 fun mk_length l = Const (length_const, fastype_of l --> HOLogic.natT) $ l |
302 fun mk_length l = Const (length_const, fastype_of l --> HOLogic.natT) $ l |
327 val mlens = map length Mss |
327 val mlens = map length Mss |
328 |
328 |
329 val indices = (n - 1 downto 0) |
329 val indices = (n - 1 downto 0) |
330 val pairs = matrix indices indices |
330 val pairs = matrix indices indices |
331 val parts = map_matrix (fn (n,m) => |
331 val parts = map_matrix (fn (n,m) => |
332 (timeap_msg (string_of_int n ^ "," ^ string_of_int m) |
332 (timeap_msg (string_of_int n ^ "," ^ string_of_int m) |
333 (setup_probe_goal thy domT Dtab Mtab) (n,m))) pairs |
333 (setup_probe_goal thy domT Dtab Mtab) (n,m))) pairs |
334 |
334 |
335 |
335 |
336 val s = fold_index (fn (i, cs) => fold_index (fn (j, Graph (G, _)) => prefix ("(" ^ string_of_int i ^ "," ^ string_of_int j ^ "): " ^ |
336 val s = fold_index (fn (i, cs) => fold_index (fn (j, Graph (G, _)) => prefix ("(" ^ string_of_int i ^ "," ^ string_of_int j ^ "): " ^ |
337 pr_graph thy G ^ ",\n") |
337 pr_graph thy G ^ ",\n") |
338 | _ => I) cs) parts "" |
338 | _ => I) cs) parts "" |
339 val _ = Output.warning s |
339 val _ = Output.warning s |
340 |
340 |
341 |
341 |
342 val ACG = map_filter (fn (Graph (G, _),(m, n)) => SOME (mk_edge (mk_number m) G (mk_number n)) | _ => NONE) (flat parts ~~ flat pairs) |
342 val ACG = map_filter (fn (Graph (G, _),(m, n)) => SOME (mk_edge (mk_number m) G (mk_number n)) | _ => NONE) (flat parts ~~ flat pairs) |
343 |> mk_set (edgeT HOLogic.natT scgT) |
343 |> mk_set (edgeT HOLogic.natT scgT) |
344 |> curry op $ (graph_const HOLogic.natT scgT) |
344 |> curry op $ (graph_const HOLogic.natT scgT) |
345 |
345 |
346 |
346 |
347 val sound_int_goal = HOLogic.mk_Trueprop (mk_sound_int ACG RDlist mfuns) |
347 val sound_int_goal = HOLogic.mk_Trueprop (mk_sound_int ACG RDlist mfuns) |
348 |
348 |
349 val tac = |
349 val tac = |
350 (SIMPSET (unfold_tac [sound_int_def, len_simp])) |
350 (SIMPSET (unfold_tac [sound_int_def, len_simp])) |
351 THEN all_less_tac (map (all_less_tac o map approx_tac) parts) |
351 THEN all_less_tac (map (all_less_tac o map approx_tac) parts) |
352 in |
352 in |
353 tac (instantiate' [] [SOME (cterm_of thy ACG), SOME (cterm_of thy mfuns)] st) |
353 tac (instantiate' [] [SOME (cterm_of thy ACG), SOME (cterm_of thy mfuns)] st) |
354 end |
354 end |
355 |
355 |
356 |
356 |
357 end |
357 end |
358 |
358 |
359 |
359 |
360 |
360 |
361 |
361 |
362 |
362 |
363 |
363 |
|
364 |