src/HOL/UNITY/Comp/TimerArray.thy
author haftmann
Mon, 01 Mar 2010 13:40:23 +0100
changeset 35416 d8d7d1b785af
parent 18556 dc39832e9280
child 36866 426d5781bb25
permissions -rw-r--r--
replaced a couple of constsdefs by definitions (also some old primrecs by modern ones)

(*  Title:      HOL/UNITY/TimerArray.thy
    Author:     Lawrence C Paulson, Cambridge University Computer Laboratory
    Copyright   1998  University of Cambridge

A trivial example of reasoning about an array of processes
*)

theory TimerArray imports "../UNITY_Main" begin

types 'a state = "nat * 'a"   (*second component allows new variables*)

definition count :: "'a state => nat" where
    "count s == fst s"
  
definition decr  :: "('a state * 'a state) set" where
    "decr == UN n uu. {((Suc n, uu), (n,uu))}"
  
definition Timer :: "'a state program" where
    "Timer == mk_total_program (UNIV, {decr}, UNIV)"


declare Timer_def [THEN def_prg_Init, simp]

declare count_def [simp] decr_def [simp]

(*Demonstrates induction, but not used in the following proof*)
lemma Timer_leadsTo_zero: "Timer : UNIV leadsTo {s. count s = 0}"
apply (rule_tac f = count in lessThan_induct, simp)
apply (case_tac "m")
 apply (force intro!: subset_imp_leadsTo)
apply (unfold Timer_def, ensures_tac "decr")
done

lemma Timer_preserves_snd [iff]: "Timer : preserves snd"
apply (rule preservesI)
apply (unfold Timer_def, safety)
done


declare PLam_stable [simp]

lemma TimerArray_leadsTo_zero:
     "finite I  
      ==> (plam i: I. Timer) : UNIV leadsTo {(s,uu). ALL i:I. s i = 0}"
apply (erule_tac A'1 = "%i. lift_set i ({0} <*> UNIV)" 
       in finite_stable_completion [THEN leadsTo_weaken])
apply auto
(*Safety property, already reduced to the single Timer case*)
 prefer 2
 apply (simp add: Timer_def, safety) 
(*Progress property for the array of Timers*)
apply (rule_tac f = "sub i o fst" in lessThan_induct)
apply (case_tac "m")
(*Annoying need to massage the conditions to have the form (... <*> UNIV)*)
apply (auto intro: subset_imp_leadsTo 
        simp add: insert_absorb 
                  lift_set_Un_distrib [symmetric] lessThan_Suc [symmetric] 
               Times_Un_distrib1 [symmetric] Times_Diff_distrib1 [symmetric])
apply (rename_tac "n")
apply (rule PLam_leadsTo_Basis)
apply (auto simp add: lessThan_Suc [symmetric])
apply (unfold Timer_def mk_total_program_def, safety) 
apply (rule_tac act = decr in totalize_transientI, auto)
done

end