|
1 (* Author: Tobias Nipkow *) |
|
2 |
|
3 theory Abs_Int1_parity_ITP |
|
4 imports Abs_Int1_ITP |
|
5 begin |
|
6 |
|
7 subsection "Parity Analysis" |
|
8 |
|
9 datatype parity = Even | Odd | Either |
|
10 |
|
11 text{* Instantiation of class @{class preord} with type @{typ parity}: *} |
|
12 |
|
13 instantiation parity :: preord |
|
14 begin |
|
15 |
|
16 text{* First the definition of the interface function @{text"\<sqsubseteq>"}. Note that |
|
17 the header of the definition must refer to the ascii name @{const le} of the |
|
18 constants as @{text le_parity} and the definition is named @{text |
|
19 le_parity_def}. Inside the definition the symbolic names can be used. *} |
|
20 |
|
21 definition le_parity where |
|
22 "x \<sqsubseteq> y = (y = Either \<or> x=y)" |
|
23 |
|
24 text{* Now the instance proof, i.e.\ the proof that the definition fulfills |
|
25 the axioms (assumptions) of the class. The initial proof-step generates the |
|
26 necessary proof obligations. *} |
|
27 |
|
28 instance |
|
29 proof |
|
30 fix x::parity show "x \<sqsubseteq> x" by(auto simp: le_parity_def) |
|
31 next |
|
32 fix x y z :: parity assume "x \<sqsubseteq> y" "y \<sqsubseteq> z" thus "x \<sqsubseteq> z" |
|
33 by(auto simp: le_parity_def) |
|
34 qed |
|
35 |
|
36 end |
|
37 |
|
38 text{* Instantiation of class @{class SL_top} with type @{typ parity}: *} |
|
39 |
|
40 instantiation parity :: SL_top |
|
41 begin |
|
42 |
|
43 |
|
44 definition join_parity where |
|
45 "x \<squnion> y = (if x \<sqsubseteq> y then y else if y \<sqsubseteq> x then x else Either)" |
|
46 |
|
47 definition Top_parity where |
|
48 "\<top> = Either" |
|
49 |
|
50 text{* Now the instance proof. This time we take a lazy shortcut: we do not |
|
51 write out the proof obligations but use the @{text goali} primitive to refer |
|
52 to the assumptions of subgoal i and @{text "case?"} to refer to the |
|
53 conclusion of subgoal i. The class axioms are presented in the same order as |
|
54 in the class definition. *} |
|
55 |
|
56 instance |
|
57 proof |
|
58 case goal1 (*join1*) show ?case by(auto simp: le_parity_def join_parity_def) |
|
59 next |
|
60 case goal2 (*join2*) show ?case by(auto simp: le_parity_def join_parity_def) |
|
61 next |
|
62 case goal3 (*join least*) thus ?case by(auto simp: le_parity_def join_parity_def) |
|
63 next |
|
64 case goal4 (*Top*) show ?case by(auto simp: le_parity_def Top_parity_def) |
|
65 qed |
|
66 |
|
67 end |
|
68 |
|
69 |
|
70 text{* Now we define the functions used for instantiating the abstract |
|
71 interpretation locales. Note that the Isabelle terminology is |
|
72 \emph{interpretation}, not \emph{instantiation} of locales, but we use |
|
73 instantiation to avoid confusion with abstract interpretation. *} |
|
74 |
|
75 fun \<gamma>_parity :: "parity \<Rightarrow> val set" where |
|
76 "\<gamma>_parity Even = {i. i mod 2 = 0}" | |
|
77 "\<gamma>_parity Odd = {i. i mod 2 = 1}" | |
|
78 "\<gamma>_parity Either = UNIV" |
|
79 |
|
80 fun num_parity :: "val \<Rightarrow> parity" where |
|
81 "num_parity i = (if i mod 2 = 0 then Even else Odd)" |
|
82 |
|
83 fun plus_parity :: "parity \<Rightarrow> parity \<Rightarrow> parity" where |
|
84 "plus_parity Even Even = Even" | |
|
85 "plus_parity Odd Odd = Even" | |
|
86 "plus_parity Even Odd = Odd" | |
|
87 "plus_parity Odd Even = Odd" | |
|
88 "plus_parity Either y = Either" | |
|
89 "plus_parity x Either = Either" |
|
90 |
|
91 text{* First we instantiate the abstract value interface and prove that the |
|
92 functions on type @{typ parity} have all the necessary properties: *} |
|
93 |
|
94 interpretation Val_abs |
|
95 where \<gamma> = \<gamma>_parity and num' = num_parity and plus' = plus_parity |
|
96 proof txt{* of the locale axioms *} |
|
97 fix a b :: parity |
|
98 assume "a \<sqsubseteq> b" thus "\<gamma>_parity a \<subseteq> \<gamma>_parity b" |
|
99 by(auto simp: le_parity_def) |
|
100 next txt{* The rest in the lazy, implicit way *} |
|
101 case goal2 show ?case by(auto simp: Top_parity_def) |
|
102 next |
|
103 case goal3 show ?case by auto |
|
104 next |
|
105 txt{* Warning: this subproof refers to the names @{text a1} and @{text a2} |
|
106 from the statement of the axiom. *} |
|
107 case goal4 thus ?case |
|
108 proof(cases a1 a2 rule: parity.exhaust[case_product parity.exhaust]) |
|
109 qed (auto simp add:mod_add_eq) |
|
110 qed |
|
111 |
|
112 text{* Instantiating the abstract interpretation locale requires no more |
|
113 proofs (they happened in the instatiation above) but delivers the |
|
114 instantiated abstract interpreter which we call AI: *} |
|
115 |
|
116 interpretation Abs_Int |
|
117 where \<gamma> = \<gamma>_parity and num' = num_parity and plus' = plus_parity |
|
118 defines aval_parity is aval' and step_parity is step' and AI_parity is AI |
|
119 .. |
|
120 |
|
121 |
|
122 subsubsection "Tests" |
|
123 |
|
124 definition "test1_parity = |
|
125 ''x'' ::= N 1; |
|
126 WHILE Less (V ''x'') (N 100) DO ''x'' ::= Plus (V ''x'') (N 2)" |
|
127 |
|
128 value "show_acom_opt (AI_parity test1_parity)" |
|
129 |
|
130 definition "test2_parity = |
|
131 ''x'' ::= N 1; |
|
132 WHILE Less (V ''x'') (N 100) DO ''x'' ::= Plus (V ''x'') (N 3)" |
|
133 |
|
134 value "show_acom ((step_parity \<top> ^^1) (anno None test2_parity))" |
|
135 value "show_acom ((step_parity \<top> ^^2) (anno None test2_parity))" |
|
136 value "show_acom ((step_parity \<top> ^^3) (anno None test2_parity))" |
|
137 value "show_acom ((step_parity \<top> ^^4) (anno None test2_parity))" |
|
138 value "show_acom ((step_parity \<top> ^^5) (anno None test2_parity))" |
|
139 value "show_acom_opt (AI_parity test2_parity)" |
|
140 |
|
141 |
|
142 subsubsection "Termination" |
|
143 |
|
144 interpretation Abs_Int_mono |
|
145 where \<gamma> = \<gamma>_parity and num' = num_parity and plus' = plus_parity |
|
146 proof |
|
147 case goal1 thus ?case |
|
148 proof(cases a1 a2 b1 b2 |
|
149 rule: parity.exhaust[case_product parity.exhaust[case_product parity.exhaust[case_product parity.exhaust]]]) (* FIXME - UGLY! *) |
|
150 qed (auto simp add:le_parity_def) |
|
151 qed |
|
152 |
|
153 |
|
154 definition m_parity :: "parity \<Rightarrow> nat" where |
|
155 "m_parity x = (if x=Either then 0 else 1)" |
|
156 |
|
157 lemma measure_parity: |
|
158 "(strict{(x::parity,y). x \<sqsubseteq> y})^-1 \<subseteq> measure m_parity" |
|
159 by(auto simp add: m_parity_def le_parity_def) |
|
160 |
|
161 lemma measure_parity_eq: |
|
162 "\<forall>x y::parity. x \<sqsubseteq> y \<and> y \<sqsubseteq> x \<longrightarrow> m_parity x = m_parity y" |
|
163 by(auto simp add: m_parity_def le_parity_def) |
|
164 |
|
165 lemma AI_parity_Some: "\<exists>c'. AI_parity c = Some c'" |
|
166 by(rule AI_Some_measure[OF measure_parity measure_parity_eq]) |
|
167 |
|
168 end |