src/HOL/BCV/Kildall.ML
author wenzelm
Tue, 28 Nov 2000 01:09:40 +0100
changeset 10527 7934b0fa8dcc
parent 10172 3daeda3d3cd0
child 10653 55f33da63366
permissions -rw-r--r--
consume facts;

(*  Title:      HOL/BCV/Kildall.thy
    ID:         $Id$
    Author:     Tobias Nipkow
    Copyright   2000 TUM
*)

Addsimps [Let_def];
Addsimps [le_iff_plus_unchanged RS sym];

Goalw [pres_type_def]
 "[| pres_type step n A; s:A; p<n |] ==> step p s : A";
by (Blast_tac 1);
qed "pres_typeD";

Goalw [bounded_def]
 "[| bounded succs n; p < n; q : set(succs p) |] ==> q < n";
by (Blast_tac 1);
qed "boundedD";

Goalw [mono_def]
 "[| mono r step n A; p < n; s:A; s <=_r t |] ==> step p s <=_r step p t";
by (Blast_tac 1);
qed "monoD";

(** merges **)

Goal "!ss. size(merges f t ps ss) = size ss";
by (induct_tac "ps" 1);
by (Auto_tac);
qed_spec_mp "length_merges";
Addsimps [length_merges];

Goalw [closed_def]
 "[| semilat(A,r,f) |] ==> \
\ !xs. xs : list n A --> x : A --> (!p : set ps. p<n) \
\      --> merges f x ps xs : list n A";
by (ftac semilatDclosedI 1);
by (rewtac closed_def);
by (induct_tac "ps" 1);
by (Auto_tac);
qed_spec_mp "merges_preserves_type";
Addsimps [merges_preserves_type];

Goal
 "[| semilat(A,r,f) |] ==> \
\ !xs. xs : list n A --> x : A --> (!p:set ps. p<size xs) --> xs <=[r] merges f x ps xs";
by (induct_tac "ps" 1);
 by (Asm_simp_tac 1);
by (Asm_full_simp_tac 1);
by (Clarify_tac 1);
by (rtac order_trans 1);
  by (Asm_simp_tac 1);
 by (etac list_update_incr 1);
   by (assume_tac 1);
  by (Asm_simp_tac 1);
 by (Asm_simp_tac 1);
by (blast_tac (claset() addSIs [listE_set]
          addIs [closedD,listE_length RS nth_in]) 1);
qed_spec_mp "merges_incr";

Goal
 "[| semilat(A,r,f) |] ==> \
\ (!xs. xs : list n A --> x:A --> (!p:set ps. p<size xs) --> \
\       (merges f x ps xs = xs) = (!p:set ps. x <=_r xs!p))";
by (induct_tac "ps" 1);
 by (Asm_simp_tac 1);
by (Clarsimp_tac 1);
by (rename_tac "p ps xs" 1);
by (rtac iffI 1);
 by (rtac context_conjI 1);
  by (subgoal_tac "xs[p := x +_f xs!p] <=[r] xs" 1);
   by (EVERY[etac subst 2, rtac merges_incr 2]);
      by (force_tac (claset() addSDs [le_listD],
                    simpset() addsimps [nth_list_update]) 1);
     by (assume_tac 1);
    by (blast_tac (claset() addSIs [listE_set]
                   addIs [closedD,listE_length RS nth_in]) 1);
   by (assume_tac 1);
  by (Asm_simp_tac 1);
 by (Clarify_tac 1);
 by (rotate_tac ~2 1);
 by (asm_full_simp_tac (simpset() addsimps
      [le_iff_plus_unchanged RS iffD1,
       list_update_same_conv RS iffD2]) 1);
by (Clarify_tac 1);
by (asm_simp_tac (simpset() addsimps
      [le_iff_plus_unchanged RS iffD1,
       list_update_same_conv RS iffD2]) 1);
qed_spec_mp "merges_same_conv";


Goalw [Listn.le_def,lesub_def,semilat_def]
 "set xs <= A --> set ys <= A --> xs <=[r] ys --> p < size xs -->  \
\ x <=_r ys!p --> semilat(A,r,f) --> x:A --> \
\ xs[p := x +_f xs!p] <=[r] ys";
by (simp_tac (simpset()  addsimps [list_all2_conv_all_nth,nth_list_update]) 1);
qed_spec_mp "list_update_le_listI";

Goalw [closed_def]
 "[| semilat(A,r,f); set ts <= A; t:A; \
\    !p. p:set ps --> t <=_r ts!p; \
\    !p. p:set ps --> p<size ts |] ==> \
\ set qs <= set ps  --> \
\ (!ss. set ss <= A --> ss <=[r] ts --> merges f t qs ss <=[r] ts)";
by (induct_tac "qs" 1);
 by (Asm_simp_tac 1);
by (Asm_simp_tac 1);
by (Clarify_tac 1);
by (rotate_tac ~2 1);
by (Asm_full_simp_tac 1);
by (EVERY[etac allE 1, etac impE 1, etac mp 2]);
 by (asm_simp_tac (simpset() addsimps [closedD]) 1);
by (asm_full_simp_tac (simpset() addsimps [list_update_le_listI]) 1);
val lemma = result();

Goal
 "[| semilat(A,r,f); t:A; set ts <= A; set ss <= A; \
\    !p. p:set ps --> t <=_r ts!p; \
\    !p. p:set ps --> p<size ts; \
\    ss <=[r] ts |] \
\ ==> merges f t ps ss <=[r] ts";
by (blast_tac (claset() addDs [lemma]) 1);
qed "merges_pres_le_ub";

Goal "[| semilat (A, r, f); t:A; p < n |] ==> !ss. ss : list n A --> \
\     (!p:set ps. p<n) --> \
\     (merges f t ps ss)!p = (if p : set ps then t +_f ss!p else ss!p)";
by (induct_tac "ps" 1);
 by (Simp_tac 1);
by (asm_simp_tac (simpset() addsimps [nth_list_update,closedD,listE_nth_in]) 1);
qed_spec_mp "nth_merges";


(** propa **)

Goal "!ss w. (!q:set qs. q < size ss) --> \
\ propa f qs t ss w = \
\ (merges f t qs ss, {q. q:set qs & t +_f ss!q ~= ss!q} Un w)";
by (induct_tac "qs" 1);
 by (Simp_tac 1);
by (Simp_tac 1);
by (Clarify_tac 1);
by (rtac conjI 1);
 by (asm_simp_tac (simpset() addsimps [nth_list_update]) 1);
 by (Blast_tac 1);
by (asm_simp_tac (simpset() addsimps [nth_list_update]) 1);
by (Blast_tac 1);
qed_spec_mp "decomp_propa";

(** iter **)

val [iter_wf,iter_tc] = iter.tcs;

goalw_cterm [] (cterm_of (sign_of thy) (HOLogic.mk_Trueprop iter_wf));
by (REPEAT(rtac wf_same_fstI 1));
by (split_all_tac 1);
by (asm_full_simp_tac (simpset() addsimps [lesssub_def]) 1);
by (REPEAT(rtac wf_same_fstI 1));
by (rtac wf_lex_prod 1);
 by (rtac wf_finite_psubset 2); (* FIXME *)
by (Clarify_tac 1);
by (dtac (semilatDorderI RS acc_le_listI) 1);
 by (assume_tac 1);
by (rewrite_goals_tac [acc_def,lesssub_def]);
by (assume_tac 1);
qed "iter_wf";

Goalw [lesssub_def]
 "[| semilat(A,r,f); ss : list n A; t:A; ! q:set qs. q < n; p:w |] ==> \
\ ss <[r] merges f t qs ss | \
\ merges f t qs ss = ss & {q. q:set qs & t +_f ss!q ~= ss!q} Un (w-{p}) < w";
by (asm_simp_tac (simpset() addsimps [merges_incr]) 1);
by (rtac impI 1);
by (dtac (sym RS (rotate_prems 4 (merges_same_conv RS iffD1))) 1);
    by (assume_tac 1);
   by (assume_tac 1);
  by (assume_tac 1);
 by (Asm_simp_tac 1);
by (asm_simp_tac (simpset() addcongs [conj_cong]
                            addsimps [le_iff_plus_unchanged RS sym]) 1);
by (blast_tac (claset() addSIs [psubsetI] addEs [equalityE]) 1);
qed "inter_tc_lemma";

goalw_cterm [] (cterm_of (sign_of thy) (HOLogic.mk_Trueprop iter_tc));
by (asm_simp_tac (simpset() addsimps [same_fst_def,pres_type_def]) 1);
by (clarify_tac (claset() delrules [disjCI]) 1);
by (subgoal_tac "(@p. p:w) : w" 1);
 by (fast_tac (claset() addIs [someI]) 2);
by (subgoal_tac "ss : list (size ss) A" 1);
 by (blast_tac (claset() addSIs [listI]) 2);
by (subgoal_tac "!q:set(succs (@ p. p : w)). q < size ss" 1);
 by (blast_tac (claset() addDs [boundedD]) 2);
by (rotate_tac 1 1);
by (asm_full_simp_tac (simpset() delsimps [listE_length]
      addsimps [decomp_propa,finite_psubset_def,inter_tc_lemma,
                bounded_nat_set_is_finite]) 1);
qed "iter_tc";

val prems = goal thy
 "(!!A r f step succs ss w. \
\    (!p. p = (@ p. p : w) & w ~= {} & semilat(A,r,f) & acc r & \
\       (!p:w. p < length ss) & bounded succs (length ss) & \
\       set ss <= A & pres_type step (length ss) A \
\     --> P A r f step succs (merges f (step p (ss!p)) (succs p) ss) \
\           ({q. q:set(succs p) & step p (ss!p) +_f ss!q ~= ss!q} Un (w-{p})))\
\    ==> P A r f step succs ss w) ==> P A r f step succs ss w";
by (res_inst_tac [("P","P")] (iter_tc RS (iter_wf RS iter.induct)) 1);
by (rename_tac "w" 1);
by (resolve_tac prems 1);
by (Clarify_tac 1);
by (asm_full_simp_tac (simpset()) 1);
by (subgoal_tac "!q:set(succs (@ p. p : w)). q < size ss" 1);
 by (rotate_tac ~1 1);
 by (asm_full_simp_tac (simpset() addsimps [decomp_propa]) 1);
by (subgoal_tac "(@p. p:w) : w" 1);
 by (fast_tac (claset() addIs [someI]) 2);
by (blast_tac (claset() addDs [boundedD]) 1);
qed "iter_induct";

Goal
 "[| semilat(A,r,f); acc r; set ss <= A; pres_type step (length ss) A; \
\    bounded succs (size ss); !p:w. p<size ss |] ==> \
\ iter(((A,r,f),step,succs),ss,w) = \
\ (if w={} then ss \
\  else let p = SOME p. p : w \
\       in iter(((A,r,f),step,succs),merges f (step p (ss!p)) (succs p) ss, \
\        {q. q:set(succs p) & step p (ss!p) +_f ss!q ~= ss!q} Un (w-{p})))";
by (rtac ((iter_tc RS (iter_wf RS (hd iter.simps))) RS trans) 1);
by (Asm_simp_tac 1);
by (rtac impI 1);
by (stac decomp_propa 1);
 by (subgoal_tac "(@p. p:w) : w" 1);
  by (fast_tac (claset() addIs [someI]) 2);
 by (blast_tac (claset() addDs [boundedD]) 1);
by (Simp_tac 1);
qed "iter_unfold";

Goalw [stable_def]
 "[| semilat (A,r,f); pres_type step n A; bounded succs n; \
\    ss : list n A; p : w; ! q:w. q < n; \
\    ! q. q < n --> q ~: w --> stable r step succs ss q; q < n; \
\    q : set (succs p) --> step p (ss ! p) +_f ss ! q = ss ! q; \
\    q ~: w | q = p  |] ==> \
\      stable r step succs (merges f (step p (ss!p)) (succs p) ss) q";
by (subgoal_tac "step p (ss!p) : A" 1);
 by (blast_tac (claset() addIs [listE_nth_in,pres_typeD]) 2);
by (Simp_tac 1);
by (Clarify_tac 1);
by (stac nth_merges 1);
     by (assume_tac 1);
    by (assume_tac 1);
   by (assume_tac 2);
  by (blast_tac (claset() addDs [boundedD]) 1);
 by (blast_tac (claset() addDs [boundedD]) 1);
by (stac nth_merges 1);
     by (assume_tac 1);
    by (assume_tac 1);
   by (assume_tac 2);
  by (blast_tac (claset() addDs [boundedD]) 1);
 by (blast_tac (claset() addDs [boundedD]) 1);
by (Simp_tac 1);
by (rtac conjI 1);
 by (Clarify_tac 1);
 by (asm_simp_tac (simpset() delsimps [listE_length]) 1);
 by (blast_tac (claset() addSIs [semilat_ub1,semilat_ub2,listE_nth_in] addIs [order_trans]addDs [boundedD]) 1);
by (blast_tac (claset() addSIs [semilat_ub1,semilat_ub2,listE_nth_in] addIs [order_trans]addDs [boundedD]) 1);
qed "stable_pres_lemma";

Goalw [stable_def]
 "[| semilat (A,r,f); mono r step n A; bounded succs n; \
\    step p (ss!p) : A; ss : list n A; ts : list n A; p < n; \
\    ss <=[r] ts; ! p. p < n --> stable r step succs ts p |] \
\ ==> merges f (step p (ss!p)) (succs p) ss <=[r] ts";
by (blast_tac (claset()
    addSIs [listE_set,monoD,listE_nth_in,le_listD,less_lengthI]
    addIs [merges_pres_le_ub,order_trans]
    addDs [pres_typeD,boundedD]) 1);
qed_spec_mp "merges_bounded_lemma";

Unify.trace_bound := 80;
Unify.search_bound := 90;
Goalw [stables_def]
 "semilat(A,r,f) & acc r & pres_type step n A & mono r step n A & \
\ bounded succs n & (! p:w. p < n) & ss:list n A & \
\ (!p<n. p~:w --> stable r step succs ss p) \
\ --> iter(((A,r,f),step,succs),ss,w) : list n A & \
\     stables r step succs (iter(((A,r,f),step,succs),ss,w)) & \
\     ss <=[r] iter(((A,r,f),step,succs),ss,w) & \
\     (! ts:list n A. \
\          ss <=[r] ts & stables r step succs ts --> \
\          iter(((A,r,f),step,succs),ss,w) <=[r] ts)";
by (res_inst_tac [("A","A"),("r","r"),("f","f"),("step","step"),("ss","ss"),("w","w")]iter_induct 1);
by (Clarify_tac 1);
by (ftac listE_length 1);
by (hyp_subst_tac 1);
by (stac iter_unfold 1);
      by (assume_tac 1);
     by (assume_tac 1);
    by (Asm_simp_tac 1);
   by (assume_tac 1);
  by (assume_tac 1);
 by (assume_tac 1);
by (asm_simp_tac (simpset() delsimps [listE_length]) 1);
by (rtac impI 1);
by (etac allE 1);
by (etac impE 1);
 by (asm_simp_tac (simpset() delsimps [listE_length]) 1);
by (subgoal_tac "(@p. p:w) : w" 1);
 by (fast_tac (claset() addIs [someI]) 2);
by (subgoal_tac "step (@ p. p : w) (ss ! (@ p. p : w)) : A" 1);
 by (blast_tac (claset() addIs [pres_typeD,listE_nth_in]) 2);
by (etac impE 1);
 by (asm_simp_tac (simpset() delsimps [listE_length,le_iff_plus_unchanged RS sym]) 1);
 by (rtac conjI 1);
  by (blast_tac (claset() addDs [boundedD]) 1);
 by (rtac conjI 1);
  by (blast_tac (claset() addIs[merges_preserves_type]addDs[boundedD]) 1);
 by (blast_tac (claset() addSIs [stable_pres_lemma]) 1);
by (asm_simp_tac (simpset() delsimps [listE_length]) 1);
by (subgoal_tac "!q:set(succs (@ p. p : w)). q < size ss" 1);
 by (blast_tac (claset() addDs [boundedD]) 2);
by (subgoal_tac "step (@ p. p : w) (ss ! (@ p. p : w)) : A" 1);
 by (blast_tac (claset() addIs [pres_typeD]) 2);
by (rtac conjI 1);
 by (blast_tac (claset() addSIs [merges_incr] addIs [le_list_trans]) 1);
by (Clarify_tac 1);
by (EVERY1[dtac bspec, atac, etac mp]);
by (asm_full_simp_tac (simpset() delsimps [listE_length]) 1);
by (blast_tac (claset() addIs [merges_bounded_lemma]) 1);
qed_spec_mp "iter_properties";


Goalw [is_dfa_def,kildall_def]
 "[| semilat(A,r,f); acc r; pres_type step n A; \
\    mono r step n A; bounded succs n|] ==> \
\ is_dfa r (kildall (A,r,f) step succs) step succs n A";
by (Clarify_tac 1);
by (Simp_tac 1);
by (rtac iter_properties 1);
by (asm_simp_tac (simpset() addsimps [unstables_def,stable_def]) 1);
by (blast_tac (claset() addSIs [le_iff_plus_unchanged RS iffD2,listE_nth_in]
              addDs [boundedD,pres_typeD]) 1);
qed "is_dfa_kildall";

Goal
 "[| semilat(A,r,f); acc r; top r T; \
\    pres_type step n A; bounded succs n; \
\    mono r step n A; wti_is_stable_topless r T step wti succs n A |] \
\ ==> is_bcv r T wti n A (kildall (A,r,f) step succs)";
by (REPEAT(ares_tac [is_bcv_dfa,is_dfa_kildall,semilatDorderI] 1));
qed "is_bcv_kildall";