src/HOL/BCV/Fixpoint.ML
author wenzelm
Wed, 27 Oct 1999 18:12:40 +0200
changeset 7956 edaca60a54cd
parent 7626 5997f35954d7
child 7961 422ac6888c7f
permissions -rw-r--r--
tuned msg;

(*  Title:      HOL/BCV/Fixpoint.ML
    ID:         $Id$
    Author:     Tobias Nipkow
    Copyright   1999 TUM
*)

goalw_cterm [] (cterm_of (sign_of thy) (HOLogic.mk_Trueprop (hd fix.tcs)));
by(asm_full_simp_tac (simpset() addsimps [wf_iff_no_infinite_down_chain]
                                addsplits [split_split]) 1);
by(Clarify_tac 1);
br ccontr 1;
by(Asm_full_simp_tac 1);
by(res_inst_tac[("x","0")] allE 1);
ba 1;
by(Clarify_tac 1);
by(rename_tac "next s0" 1);
by(subgoal_tac "!i. fst(f i) = next" 1);
by(eres_inst_tac[("x","%i. snd(f i)")] allE 1);
by(Asm_full_simp_tac 1);
by(Clarify_tac 1);
by(eres_inst_tac[("x","i")] allE 1);
by(eres_inst_tac[("x","i")] allE 1);
by(Force_tac 1);
br allI 1;
by(induct_tac "i" 1);
by(Asm_simp_tac 1);
by(eres_inst_tac[("x","n")] allE 1);
by(Auto_tac);
val fix_tc = result();

Goalw [wf_iff_no_infinite_down_chain RS eq_reflection]
 "[| wf{(t,s). s:A & next s = Some t & t ~= s}; \
\    !a:A. next a : option A; s:A |] ==> \
\ fix(next,s) = (case next s of None => False \
\                | Some t => if t=s then True else fix(next,t))";
by(stac (fix_tc RS (hd fix.rules)) 1);
by(Simp_tac 1);
by(Clarify_tac 1);
by(subgoal_tac "!i. f i : A" 1);
 by(Blast_tac 1);
br allI 1;
by(induct_tac "i" 1);
 by(Asm_simp_tac 1);
by(Auto_tac);
qed "fix_unfold";

(* Thm: next has fixpoint above s iff fix(next,s) *)

Goal "[| x = Some y; x : option A |] ==> y : A";
by(Blast_tac 1);
val lemma = result();

Goal
"[| acc L; \
\   !t:L. !s:L. next t = Some t & s <= t --> (? u. next s = Some u & u <= t); \
\   !a:L. next a : option L; !a:L. !b. next a = Some b --> a <= b |] \
\ ==> s:L --> fix(next,s) = (? t:L. s <= t & next t = Some t)";
by(subgoal_tac "wf{(y,x::'a::order). x : L & next x = Some y & y ~= x}" 1);
 by(full_simp_tac (simpset() addsimps [acc_def]) 2);
 be wf_subset 2;
 by(simp_tac (simpset() addsimps [order_less_le]) 2);
 by(blast_tac (claset() addDs [lemma]) 2);
by(res_inst_tac [("a","s")] wf_induct 1);
 ba 1;
by(Clarify_tac 1);
by(Full_simp_tac 1);
by(stac fix_unfold 1);
   ba 1;
  ba 1;
 ba 1;
by(split_tac [option.split] 1);
br conjI 1;
 by(thin_tac "!a:L. !b. next a = Some b --> a <= b" 1);
 by(Force_tac 1);
by(Clarify_tac 1);
by(split_tac [split_if] 1);
br conjI 1;
 by(Blast_tac 1);
by(Clarify_tac 1);
by(EVERY[etac allE 1, etac impE 1, etac impE 2, etac trans 3]);
  by(Blast_tac 1);
 be lemma 1;
 by(Blast_tac 1);
br iffI 1;
 by(blast_tac (claset() addIs [order_trans]) 1);
by(Clarify_tac 1);
by(EVERY[rtac bexI 1, atac 2, rtac conjI 1, atac 2]);
by(thin_tac "!a:L. !b. next a = Some b --> a <= b" 1);
by(Force_tac 1);
qed_spec_mp "fix_iff_has_fixpoint";


(* This lemma looks more pleasing to the eye, because of the monotonicity
assumption for next, instead of the strange assumption above.
However, function next as defined in DFAimpl is NOT monotone because
None is not required to be detected as early as possible. Thus the following
does not hold: sos <= tos & next sos = None ==> next tos = None

Goal
"[| wf{(y,x::'a::order). x : L & next x = Some y & y ~= x}; \
\   !t:L. !s:L. s <= t & next s = None --> next t = None; \
\   !t:L. !s:L. !u. s <= t & next s = Some u --> \
\                   next t = None | (? v. next t = Some v & u <= v); \
\   !a:L. next a : option L; !a:L. !b. next a = Some b --> a <= b |] \
\ ==> s:L --> fix(next,s) = (? t:L. s <= t & next t = Some t)";
by(res_inst_tac [("a","s")] wf_induct 1);
 ba 1;
by(Clarify_tac 1);
by(Full_simp_tac 1);
by(stac fix_unfold 1);
   ba 1;
  ba 1;
 ba 1;
by(split_tac [option.split] 1);
br conjI 1;
 by(blast_tac (claset() addDs [sym RS trans]) 1);
by(Clarify_tac 1);
by(split_tac [split_if] 1);
br conjI 1;
 by(Blast_tac 1);
by(Clarify_tac 1);
by(EVERY[etac allE 1, etac impE 1, etac impE 2, etac trans 3]);
  by(Blast_tac 1);
 be lemma 1;
 by(Blast_tac 1);
br iffI 1;
 by(subgoal_tac "next a ~= None" 1);
  by(Clarify_tac 1);
  by(EVERY[etac ballE 1, etac ballE 1, etac allE 1, etac impE 1,etac disjE 2]);
      br conjI 1;
       ba 1;
      ba 1;
     by(blast_tac (claset() addDs [sym RS trans]) 1);
    by(blast_tac (claset() addIs [order_trans]) 1);
   by(blast_tac (claset() addIs [order_trans]) 1);
  by(Blast_tac 1);
 br notI 1;
 by(Clarify_tac 1);
 by(blast_tac (claset() addDs [sym RS trans,lemma]) 1);
by(blast_tac (claset() addDs [sym RS trans]) 1);
qed_spec_mp "fix_iff_has_fixpoint";
*)