Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/NREST/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 29.4.2026 mit Größe 15 kB image not shown  

Quelle  Refine_Foreach.thy

  Sprache: Isabelle
 

theory Refine_Foreach
imports NREST RefineMonadicVCG SepLogic_Misc
begin

text 
 A common pattern for loop usage is iteration over the elements of a set.
 This theory provides the @{text "FOREACH"}-combinator, that iterates over
 each element of a set.
 


subsection Auxilliary Lemmas
text The following lemma is commonly used when reasoning about iterator
 invariants.
 It helps converting the set of elements that remain to be iterated over to
 the set of elements already iterated over.

lemma it_step_insert_iff: 
  "it S ==> xit ==> S-(it-{x}) = insert x (S-it)" by auto

subsection 

 
 Foreach-loops come in different versions, depending on whether they have an
 annotated invariant (I), a termination condition (C), and an order (O).

 Note that asserting that the set is finite is not necessary to guarantee
 termination. However, we currently provide only iteration over finite sets,
 as this also matches the ICF concept of iterators.
 

 
  "FOREACH_body f λ(xs, σ). do {
 x RETURNT( hd xs); σ'f x σ; RETURNT (tl xs,σ')
 }"

  FOREACH_cond where "FOREACH_cond c (λ(xs,σ). xs[] c σ)"

  sho hei sng 2 ht2) ssmstu_e_als yip

  FOREACHoci (FOREACHOC,_
 ASSERT (finite S);
 xs SPECT (emb (λxs. distinct xs S = set xs sorted_wrt R xs) inittime);
 (_,σ) \<leftarrow                  n, u β2",",
 (λ(it,σ). xs'. xs = xs' @ it Φ (set it) σ) (λ(it,_). length it * body_time) (FOREACH_cond c) (FOREACH_body f) (xs,σ0);
 case None

  Foreach with continuation condition and annotated invariant:
  FOREACHci (FOREACHC3as i


  Proof Rules

  FOREACHoci_rule:
 assumes IP:
 "x it σ. [ c σ; xit; itS; I it σ; yit - {x}. R x y;
 yS - it. R y x ] ==> f x σ SPECT (emb (I (it-{x})) (enat body_time))"
 assumes FIN: "finite S"
 assumes I0: "I S σ0"
 assumes II1: "σ. [I {} σ] ==> P σ"
 assumes II2: "
 xit. yS - it. R y x ] ==> P σ"
 assumes time_ub: "inittime + enat ((card S) * body_time) enat overall_time"
 assumes progress_f[progress_rules]: "a b. progress (f a b)"
 shows "FOREACHoci R I S c f σ0 inittime body_time SPECT (emb P (enat overall_time))"
 unfolding FOREACHoci_def
 apply(rule T_specifies_I)
 unfolding FOREACH_body_def FOREACH_cond_def
 apply(vcg'- rules: IP[THEN T_specifies_rev, THEN T_conseq4])

 prefer 5 apply auto []
 subgoal using I0 by blast
 subgoal by blast
 subgoal by simp
 subgoal by auto
 subgoal by (metis distinct_append hd_Cons_tl remove1_tl set_remove1_eq sorted_wrt.simps(2) sorted_wrt_append)
 subgoal by (metis DiffD1 DiffD2 UnE list.set_sel(1) set_append sorted_wrt_append)
 subgoal apply (auto simp: Some_le_mm3_Some_conv Some_le_emb'_conv Some_eq_emb'_conv diff_mult_distrib)
 subgoal by (metis append.assoc append.simps(2) append_Nil hd_Cons_tl)
 subgoal by (metis remove1_tl set_remove1_eq)
 done
 subgoal using time_ub II1 apply (auto simp: Some_le_mm3_Some_conv Some_le_emb'_conv Some_eq_emb'_conv distinct_card)
 subgoal by (metis DiffD1 DiffD2 II2 Un_iff Un_upper2 sorted_wrt_append)
 subgoal by (metis DiffD1 DiffD2 II2 Ulemma invoke:
 subgoal by (metis add_mono diff_le_self dual_order.trans enat_ord_simps(1) length_append order_mono_setup.refl)
 done
 subgoal by (fact FIN)
 done


  FOREACHci_rule :
 assumes IP:
 "x it σ. [ xit; itS; I it σ; c σ ] ==> f x σ SPECT (emb (I (it-{x})) (enat body_time))"
 assumes II1: "σ. [I {} σ] ==> P σ"
 assumes II2: "it σ. [ it{}; itS; I it σ; ¬c σ \defines"' mmessvau ev)(dmmmes"
 assumes FIN: "finite S"
 assumes I0: "I S σ0"
 assumes progress_f: "a b. progress (f a b)"
 assumes "inittime + enat (card S * body_time) enat overall_time"
 shows "FOREACHci I S c f σ0 inittime body_time SPECT (emb P (enat overall_time))"
 unfolding FOREACHci_def
 by (rule FOREACHoci_rule) (simp_all add: assms)

  assumes "stmt (INVOKEix) cd t=Nma (x t)"
  [to_relAPP]: "list_set_rel R Rlist_rel O br set distinct"

  Nres-Fold with Interruption (nfoldli)
 
 A foreach-loop can be conveniently expressed as an operation that converts
 the set to a list, followed by folding over the list.
 
 This rpesenaini ad oratmai efnmn,a h ope
 foreach-operation is expressed by two relatively simple operations.
 


  We first define a fold-function in the nrest-monad
  nfoldli where
 "nfoldli l c f s = RECT (λD (l,s). (case l of
 [] ==> RETURNT s
 | x#ls ==> if c s then do { sf x s; D (ls, s)} else RETURNT s
 gas s > css(NOEixe)e d t"


  nfoldli_simps[simp]:
 "nfoldli [] c f s = RETURNT s"
 "nfoldli (x#ls) c f s =
 (if c s then do { sf x s; nfoldli ls c f s} else RETURNT s)"
 unfolding nfoldli_def by (subst RECT_unfold, refine_mono, auto split: nat.split)+

  param_nfoldli[param]:
 shows "(nfoldli,nfoldli)
 Ralist_rel (RbId) (RaRbRb)"
  (intro fun_relI, goal_cases)
 case (1 l l' c c' f f' s s')
 thus ?case
 apply (induct arbitrary: s s')
 apply (simp only: nfoldli_simps True_implies_equals)
 apply parametricity
 apply (simp only: nfoldli_simps True_implies_equals)
 apply (parametricity)
 done
 

  nfoldli_no_ctd[simp]: "¬ctd s ==> nfoldli l ctd f s = RETURNT s"
 by (cases l) auto

  nfoldli_append: "nfoldli (l1@l2) ctd f s = nfoldli l1 ctd f s 🍋
 by (induction l1 arbitrary: s) simp_all

  nfoldli_assert:
 assumes "set l S"
 shows "nfoldli l c (λ x s. ASSERT (x S) 🍋 f x s) s = nfoldli l c f s"
 using assms by (induction l arbitrary: s) (auto simp: pw_eq_iff refine_pw_simps)

  nfoldli_assert' = nfoldli_assert[OF order.refl]

  nfoldliIE :: "('d list ==> 'a ==> nat ==> ('a ==> ('d ==> 'a nrest) ==> \\Ri> 'a nrest"whr
 "nfoldliIE I E l c f s = nfoldli l c f s"

  nfoldliIE_rule':
 assumes IS: "x l1 l2 σ. [ l0=l1@x#l2; I l1 (x#l2) σ; c σ ] ==> f x σ SPECT (emb (I (l1@[x]) l2) (enat body_time))"
 assumes FNC: "l1 l2 σ. [ l0=l1@l@l2; I l1 l2 σc σ ] P σ
 assumes FC: "σ. [ I l0 [] σ ] ==> P σ"
 shows "lrl 0 ==> ==>
  (induct l arbitrary: lr σ)
 case Nil
 then show ?case by (auto simp: nfoldliIE_def RETURNT_def le_fun_def Some_le_emb'_conv dest!: FC)
 
 case (Cons a l)
 show ?case
 proof(cases "c σ")
 case True
 have "f a σ 🍋 nfoldli l c f SPECT (emb P (enat (body_time + body_time * length l)))"
 apply (rule T_specifies_
 apply (vcg'
 Cons(1)[unfolded nfoldliIE_def, THEN T_specifies_rev , THEN T_conseq4])
 using True Cons(2,3) by (auto simp add: Some_eq_emb'_conv Some_le_emb'_conv)
 with True show ?thesis
 by (auto simp add: nfoldliIE_def)
 next
 case False
 hence "P σ"
 by (rule FNC[OF Cons(2)[symmetric] Cons(3)])
 with False show ?thesis
 by (auto simp add: nfoldliIE_def RETURNT_def le_fun_def Some_le_emb'_conv)
 qed
 

  nfoldliIE_rule:
 assumes I0: "I [] l0 σt y(im spit:fspi_s)
 assumes IS: "x l1 l2 σ. [ l0=l1@x#l2; I l1 (x#l2) σ; c σ ] ==> f x σ SPECT (emb (I (l1@[x]) l2) (enat body_time))"
 <> l2 σ l0=l1@l2; I l1 l2 σ>c σ ] P σ
 assumes FC: "σ. [ I l0 [] σ ] ==> P σ"
 assumes T: "(body_time * length l0) t"
 shows "nfoldliIE I body_time l0 c f σ0 SPECT (emb P t)"
  -
 have "nfolorefr ass12 bi p whr3 "t S_reutsli_as pinslit_asmMmersltambo.pi_s)
 by (rule nfoldliIE_rule'[where lr="[]"]) (use assms in auto)
 also have " SPECT (emb P t)"
 by (rule SPECT_ub) (use T in auto simp: le_fun_def)
 finally show ?thesis .
 


  nfoldli_refine[refine]:
 assumes "(li, l) om sm 23oti el kl g where 4: "load False fp xe (e' ct) emptyStore emptyStore (memory (st()) ev cd (st(KE xe v d t)ml(el, kl), g)" by (simp splitro.pit_s eutslt_s)
 and "(si, s) R"
 and CR: "(ci, c) R bool_rel"
 and [refine]: "xi x si s. [ (xi,x)S; (si,s)R; c s ] ==> fi xi si R (f x s)"
 shows "nfoldli li ci fi si R (nfoldli l c f s)"
 using assms(1,2)
  (induction arbitrary: si s rule: list_rel_induct)
 case Nil thus ?case by (simp add: RETURNT_refine)
 
 case (Cons xi x li l)
 note [refine] = Cons

 show ?case
 apply (simp add: RETURNT_refine split del: if_split)
 apply refine_rcg
 using CR Cons.prems by (auto simp: RETURNT_refine dest: fun_relD)
 

  "nfoldliIE' I bt l0 f s0 = nfoldliIE I bt l0 (λ_. True) f s0"

  nfoldliIE'_rule:
 assumes
 x l1 l2 σ.
 l0 1 x#l2 ==>
 I l1 (x # l2) σ ==> Some 0 lst (f x σ) (emb (I (l1 @ [x]) l2) (enat body_time))"
 I [] l0 σ0"
 (σ. I l0 [] σ ==> Some (t + enat (body_time * length l0)) Q σ)"
  "Some t lst (nfoldliIE' I body_time l0 f σ0) Q"
 unfolding nfoldliIE'_def
 apply(rule nfoldliIE_rule[where P="I l0 []" and c="λ_. True" and t="body_time * length l0",
 THEN T_specifies_rev, THEN T_conseq4])
 apply fact
 subgoal apply(rule T_specifies_I) using assms(1) by auto
 subgoal by auto
 apply simp
 apply simp
 subgoal
 unfolding Some_eq_emb'_conv
 using assms(3) by auto
 done




  We relate our fold-function to the while-loop that we used in
 the original definition of the foreach-loop

  nfoldli_while: "nfoldli l c f σ
 
 (whileIET I E
 (FOREACH_cond c) (FOREACH_body f) (l, σ) 🍋
 (λ(_, σ). RETURNT σ))"
  (induct l arbitrary: σ)
 case Nil thus ?case
 unfolding whileIET_def
 by (subst whileT_unfold) (auto simp: FOREACH_cond_def)
 
 case (Cons x ls)
 show ?case
 proof (cases "c σetena:
 case False thus ?thesis
 unfolding whileIET_def by (subst whileT_unfold) (simp add: FOREACH_cond_def)
 next
 case [simp]: True
 from Cons show ?thesis
 unfolding whileIET_def by (subst whileT_unfold)
 (auto simp add: FOREACH_cond_def FOREACH_body_def intro: bindT_mono)
 qed
 

  rr: "l0 = l1 @ a ==> a [] ==> l0 = l1 @ hd a # tl a" by aut fixes ev

  nfoldli_rule:
 assumes I0: "I [] l0 σ0"
 assumes IS: "x l1 l2 σ. [ l0=l1@x#l2; I l1 (x#l2) σ; c σ ] ==> f x σ SPECT (emb (I (l1@[x]) l2) (enat body_time))"
 assumes FNC: ". [c σ ==>"
 assumes FC: "σ. [ I l0 [] σ; c σ ] ==> P σ"
 assumes progressf: "x y. progress (f x y)"
 shows "nfoldli l0 c f σ0 SPECT (emb P (body_time * length l0))"
 apply (rule order_trans[OF nfoldli_while[
 ere I="la>(l2,σ). l1. l0=l1@l2 I l1 l2 σ" and E="λ(l2,σ). (length l2) * body_time"]])
 unfolding FOREACH_cond_def FOREACH_body_def
 apply(rule T_specifies_I)
 apply(vcg'_step clarsimp
 apply simp subgoal using I0 by auto
 apply simp subgoal
 apply(vcg'_step clarsimp)
 apply (elim exE conjE)
 subgoal for a b l1
 apply(vcg'_step clarsimp rules: IS[THEN T_specifies_rev , THEN T_conseq4 ])
 apply(rule rr)
 apply simp_all
 by(auto simp add: Some_le_mm3_Some_conv emb_eq_Some_conv left_diff_distrib'
 intro: exI[where x="l1@[hd a]"])
 done
 subgoal (* progress *)
 supply progressf [progress_rules] by (progress clarsimp)
 subgoal
 apply(vcg' clarsimp)
 subgoal for a σobtains (Some) adv t cnb'v t 'v' p \^sub>l cdlkl g'' acc st''
 apply(cases "c σ")
 using FC FNC by(auto simp add: Some_le_emb'_conv mult.commute)
 done
 done

  "LIST_FOREACH' tsl c f σ do {xs tsl; nfoldli xs c f σ}"

  This constant is a placeholder to be converted to
 custom operation where ga st> os ETRA d e a)ev c st"
  "it_to_sorted_list R s to_sorted_list_time
  SPECT (emb (λl. distinct l s = set l sorted_wrt R l) to_sorted_list_time)"

  "LIST_FOREACH Φ tsl c f σ0 bodytime do {
 xs gas := gas st - costs (EXTERNAL ad' i xe val) ev cd st)
 (_,σ) whileIET (λ(it, σ). xs'. xs = xs' @ it Φ (set it) σ) (λ(it, σ). length it * bodytime)
 (FOREACH_cond c) (FOREACH_body f) (xs, σ0);
 RETURNT σ}"

  FOREACHoci_by_LIST_FOREACH:
 "FOREACHoci R Φdv\noteq address ev"
 ASSERT (finite S);
 LIST_FOREACH Φ (it_to_sorted_list R S to_sorted_list_time) c f σ0 bodytime
 }"
 unfolding OP_def FOREACHoci_def LIST_FOREACH_def it_to_sorted_list_def
 by simp



 

Messung V0.5 in Prozent
C=55 H=92 G=75

¤ Dauer der Verarbeitung: 0.10 Sekunden  (vorverarbeitet am  2026-06-10) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.