Theory Nielson_Examples
theory Nielson_Examples
imports Nielson_VCG
begin
subsubsection ‹example›
lemma "⊢⇩1 {%l s. True} SKIP;; SKIP { %s. 1 ⇓ %l s. True}"
proof -
let ?T = "%l s. True"
have "⊢⇩1 {%l s. True} strip (Aconseq ?T ?T (%s. 1) (Aseq Askip Askip)) { %s. 1 ⇓ %l s. True}"
apply(rule vc_sound'') by auto
then show ?thesis by simp
qed
lemma "finite (support P) ⟹ ⊢⇩1 {P} strip Askip {time Askip ⇓ P}"
apply(rule vc_sound')
apply(simp)
apply(simp)
apply(simp)
apply(simp) done
lemma support_single2: "support (λl s. P s) = {}"
unfolding support_def by fastforce
lemma "⊢⇩1 { %l s. True } strip (Aassign a (N 1)) {time (Aassign a (N 1)) ⇓ %l s. s a = 1}"
apply(rule vc_sound')
apply(simp_all add: support_single2) done
lemma "⊢⇩1 { %l s. True } strip ( (a ::= (N 1)) ;; Askip ) {time ( (a ::= (N 1)) ;; Askip ) ⇓ %l s. s a = 1}"
apply(rule vc_sound')
apply(simp_all add: support_single2) done
lemma "⊢⇩1 { %l s. True } strip ( (a ::= (N 1)) ;; b ::= (V a) ) {time ( (a ::= (N 1)) ;; b ::= (V a) ) ⇓ %l s. s b = 1}"
apply(rule vc_sound')
by(simp_all add: support_single2)
lemma assumes
E: "E = (%s. 1 + 2 * (4 - nat (s a)))" and
C: "C = ({(I,(S,(E)))} WHILE Less (V a) (N 3) DO a ::= Plus (V a) (N 1) )"
shows "⋀s. 0 ≤ s a ⟹ time C s ≤ 9"
unfolding C E apply(simp) done
paragraph "Count up to 3"
lemma example_count_upto_3: assumes
I: "I = (%l s. s a ≥ 0)" and
E: "E = (%s. 1 + 2 * (4 - nat (s a)))" and
S: "S = (%s. (if s a ≥ 3 then s else s(a:=3) ))" and
C: "C = ({(I,(S,(E)))} WHILE Less (V a) (N 3) DO a ::= Plus (V a) (N 1) )"
shows "⊢⇩1 { %l s. 0 ≤ s a } strip C {time C ⇓ %l s. True }"
unfolding C
apply(rule vc_sound')
subgoal
apply(simp)
apply(safe)
subgoal unfolding I by simp
subgoal unfolding I E by simp
subgoal unfolding S by auto
subgoal unfolding I E by auto
subgoal unfolding I S by auto
done
subgoal
by simp
subgoal
unfolding I by(simp add: support_inv)
subgoal unfolding I by simp
done
paragraph "Count up to b"
lemma example_count_upto_b: assumes
I: "I = (%l s. s a ≥ 0 )" and
E: "E = (%s. 1 + 2 * ((nat b+1) - nat (s a)))" and
S: "S = (%s. (if s a ≥ b then s else s(a:=b) ))" and
C: "C = ({(I,(S,(E)))} WHILE Less (V a) (N b) DO a ::= Plus (V a) (N 1) )"
shows "⊢⇩1 { %l s. 0 ≤ s a } strip C {time C ⇓ %l s. True }"
unfolding C
apply(rule vc_sound') by(auto simp: I E S support_inv)
paragraph " Example: multiplication by repeated addition"
lemma helper: "(A::int) * B + B = (A+1) * B" by(auto simp: distrib_right)
lemma mult: assumes
I: "I = (%l s. s ''a'' ≥ 0 ∧ s ''a'' ≥ s ''z'' ∧ s ''z'' ≥ 0 ∧ s ''y'' = s ''z'' * (s ''b'') )" and
E: "E = (%s. 1 + 3 * ((nat (s ''a'') + 1) - nat (s ''z'')))" and
S: "S = (%s. (if s ''z'' ≥ s ''a'' then s else s(''y'':=(s ''a'') * (s ''b''), ''z'':=s ''a'' ) ))" and
C: "C = (''y'' ::= (N 0);; ''z'' ::= (N 0) ;; {(I,(S,(E)))} WHILE Less (V ''z'') (V ''a'') DO (''y'' ::= Plus (V ''y'') (V ''b'') ;; ''z'' ::= Plus (V ''z'') (N 1)) )" and
f: "f = (%s. 3 * (nat(s ''a'') + 2))"
shows "⊢⇩1 { %l s. 0 ≤ s ''a'' } strip C { f ⇓ %l s. s ''y'' = s ''a'' * (s ''b'') }"
unfolding C
apply(rule vc_sound'')
apply(auto simp: I E S distrib_right support_inv f)
subgoal for s by (auto simp add: helper)
done
lemma mult_abstract: assumes
I: "I = (%l s. s ''a'' ≥ 0 ∧ s ''a'' ≥ s ''z'' ∧ s ''z'' ≥ 0 ∧ s ''y'' = s ''z'' * (s ''b'') )" and
E: "E = (%s. 1 + 2* ((nat (s ''a'') + 1) - nat (s ''z'')))" and
S: "S = (%s. (if s ''z'' ≥ s ''a'' then s else s(''y'':=(s ''a'') * (s ''b''), ''z'':=s ''a'' ) ))" and
e: "e = (%s. 1)" and
lb[simp]: "(lb::acom) = ({λl s. I l s ∧ s ''z'' < s ''a'' /I/e} CONSEQ (''y'' ::= Plus (V ''y'') (V ''b'') ;; ''z'' ::= Plus (V ''z'') (N 1)) )" and
l[simp]: "(l::acom) = {(I,(S,(E)))} WHILE (Less (V ''z'') (V ''a'')) DO lb" and
e'[simp]: "e' = (%s. 1 + (nat (s ''a'')))" and
wl[simp]: "(wl::acom) = {I/λl s. I l s ∧ s ''z'' ≥ s ''a''/e'} CONSEQ l" and
C: "(C::acom) = (''y'' ::= (N 0);; ''z'' ::= (N 0) ;; wl )" and
f: "f = (%s. nat(s ''a'') + 1)"
shows "⊢⇩1 { %l s. 0 ≤ s ''a'' } strip ( {%l s. 0 ≤ s ''a''/ %l s. s ''y'' = s ''a'' * (s ''b'')/ f} CONSEQ C) { f ⇓ %l s. s ''y'' = s ''a'' * (s ''b'') }"
unfolding C
apply(rule vc_sound'')
apply(auto simp: I E S distrib_right support_inv f e)
subgoal for s by (auto simp add: helper)
apply(rule exI[where x=100]) apply auto
apply(rule exI[where x=100]) apply auto
done
paragraph ‹Example: nested loops›
lemma nested: assumes
I2: "I2 = (%l s. s ''a'' ≥ 0 ∧ s ''b'' ≥ 0 ∧ s ''a'' > s ''z'' ∧ s ''z'' ≥ 0 ∧ s ''b'' ≥ s ''g'' ∧ s ''g'' ≥ 0 ∧ s ''y'' = (s ''z'') * (s ''b'') + s ''g'' )" and
I1: "I1 = (%l s. s ''a'' ≥ 0 ∧ s ''b'' ≥ 0 ∧ s ''a'' ≥ s ''z'' ∧ s ''z'' ≥ 0 ∧ s ''y'' = s ''z'' * (s ''b'') )" and
E2: "E2 = (%s. 1 + 3 * ((nat (s ''b'') ) - nat (s ''g'')))" and
S2: "S2 = (%s. (if s ''g'' ≥ s ''b'' then s else s(''y'':=(s ''z'') * (s ''b'') + s ''b'' , ''g'':=s ''b'' ) ))" and
E1: "E1 = (%s. 1 + ( 4 + (3 * ((nat (s ''b'') ))) ) * ((nat (s ''a'') ) - nat (s ''z'')))" and
S1: "S1 = (%s. (if s ''z'' ≥ s ''a'' then s else s(''y'':=(s ''a'') * (s ''b''), ''z'':=s ''a'', ''g'':=s ''b'' ) ))" and
C: "C = (''y'' ::= (N 0);;
''z'' ::= (N 0) ;;
{(I1,(S1,(E1)))} WHILE Less (V ''z'') (V ''a'') DO
(
''g'' ::= (N 0) ;;
(
{(I2,(S2,(E2)))} WHILE Less (V ''g'') (V ''b'') DO
(''y'' ::= Plus (V ''y'') (N 1);;
''g'' ::= Plus (V ''g'') (N 1))
) ;;
''z'' ::= Plus (V ''z'') (N 1))
)" and
f: "f = (%s. 3 + 4*nat(s ''a'')+ 3 * (nat(s ''a'') * nat(s ''b'')))"
shows "⊢⇩1 { %l s. 0 ≤ s ''a'' ∧ s ''b'' ≥ 0 } strip C { f ⇓ %l s. s ''y'' = s ''a'' * (s ''b'') }"
unfolding C
apply(rule vc_sound'')
proof( goal_cases)
case 1
show ?case apply(simp)
proof(safe, goal_cases)
case (1 l s)
from 1 show ?case unfolding I1 unfolding I2 by(auto )
next
case (2 l s)
then show ?case unfolding I1 S2 apply(auto) unfolding E2 apply(simp) unfolding E2 apply(auto)
unfolding E1 apply(simp)
apply(simp)
proof (goal_cases)
case 1
then have g: "s ''a'' > s ''z''" by linarith
then have p: "(nat (s ''a'') - nat (s ''z'' + 1)) = (nat (s ''a'') - nat (s ''z'')) - 1" and z: "(nat (s ''a'') - nat (s ''z'')) ≥ 1"
using "1" apply linarith
using g 1 by linarith
have "Suc (Suc (Suc (Suc ((4 + 3 * nat (s ''b'')) * (nat (s ''a'') - nat (s ''z'' + 1)) + 3 * nat (s ''b''))))) =
4 + ((4 + 3 * nat (s ''b'')) * (nat (s ''a'') - nat (s ''z'' + 1)) + 3 * nat (s ''b''))
" by auto
also
have "… = 4 + ( (4 + 3 * nat (s ''b'')) * (nat (s ''a'') - nat (s ''z'')) - (4 + 3 * nat (s ''b'')) + 3 * nat (s ''b''))"
apply(simp only: p)
proof -
have "⋀n na. (n::nat) * na - n = n * (na - 1)"
by (simp add: diff_mult_distrib2)
then show "4 + ((4 + 3 * nat (s ''b'')) * (nat (s ''a'') - nat (s ''z'') - 1) + 3 * nat (s ''b'')) = 4 + ((4 + 3 * nat (s ''b'')) * (nat (s ''a'') - nat (s ''z'')) - (4 + 3 * nat (s ''b'')) + 3 * nat (s ''b''))"
by presburger
qed
also
have "… = (4 + 3 * nat (s ''b'')) * (nat (s ''a'') - nat (s ''z''))"
using z
by (smt ‹4 + ((4 + 3 * nat (s ''b'')) * (nat (s ''a'') - nat (s ''z'' + 1)) + 3 * nat (s ''b'')) = 4 + ((4 + 3 * nat (s ''b'')) * (nat (s ''a'') - nat (s ''z'')) - (4 + 3 * nat (s ''b'')) + 3 * nat (s ''b''))› add.left_commute diff_add distrib_left mult.right_neutral p)
finally show ?case by simp
qed
next
case (3 l s)
{ fix i :: int assume "0 ≤ i" then have "int (∑{0..<nat i}) + i = int (∑{0..nat i})"
by (simp add: sum.last_plus) } note bla=this
from 3 show ?case unfolding I1 S1 S2 apply(auto simp add: )
proof (goal_cases)
case 1
then have a: "s ''a'' = s ''z'' + 1" by linarith
show ?case apply(simp only: a) using 1
by (simp add: distrib_left mult.commute fun_upd_twist)
qed
next
case (4 l s)
then show ?case unfolding I1 by (auto)
next
case (5 l s)
then show ?case unfolding I1 E1 by auto
next
case (6 l s)
then show ?case unfolding I1 S1 by(simp)
next
case (7 l s)
then show ?case unfolding I2 apply(simp) done
next
case (8 l s)
then show ?case unfolding I2 apply(auto) unfolding E2 by(auto)
next
case (9 l s)
{ fix i :: int assume "0 ≤ i" then have "int (∑{0..<nat i}) + i = int (∑{0..nat i})"
by (simp add: sum.last_plus) } note bla=this
from 9 show ?case unfolding I2 S2 apply(auto simp add: ) done
next
case (10 l s)
then show ?case unfolding I2 I1 by (auto simp add: distrib_left mult.commute)
next
case (11 l s)
then show ?case unfolding I2 E2 by (simp)
next
case (12 l s)
then show ?case unfolding I2 S2 by(simp)
qed
next
case 2
show ?case apply (rule exI[where x=1]) by (auto simp add: I1 C E1 f distrib_left mult.commute)
qed (auto simp: I1 I2 support_single2)
paragraph "with logical variables"
lemma fin_sup_single: "finite (support (λl. P (l a)))"
apply(rule finite_subset[OF support_single]) by simp
lemmas fin_support = fin_sup_single
lemma finite_support_and: "finite (support A) ⟹ finite (support B) ⟹ finite (support (λl s. A l s ∧ B l s))"
apply(rule finite_subset[OF support_and]) by blast
end