source: src/ASM/Policy.ma @ 1879

Last change on this file since 1879 was 1879, checked in by boender, 8 years ago
  • Policy compiles until the end, still some (fairly trivial) cases daemon left
File size: 76.7 KB
Line 
1include "ASM/ASM.ma".
2include "ASM/Arithmetic.ma".
3include "ASM/Fetch.ma".
4include "ASM/Status.ma".
5include alias "basics/logic.ma".
6include alias "arithmetics/nat.ma".
7include "utilities/extralib.ma".
8include "ASM/Assembly.ma".
9
10(* Internal types *)
11
12(* label_map: identifier ↦ 〈instruction number, address〉 *)
13definition label_map ≝ identifier_map ASMTag (ℕ × ℕ).
14
15(* jump_expansion_policy: instruction number ↦ 〈pc, [addr, jump_length]〉 *)
16definition jump_expansion_policy ≝ ℕ × (BitVectorTrie (ℕ × ℕ × jump_length) 16).
17
18(* The different properties that we want/need to prove at some point *)
19(* Anything that's not in the program doesn't end up in the policy *)
20definition out_of_program_none ≝
21  λprefix:list labelled_instruction.λpolicy:jump_expansion_policy.
22  ∀i.i ≥ |prefix| → i < 2^16 → lookup_opt … (bitvector_of_nat ? i) (\snd policy) = None ?.
23
24(* If instruction i is a jump, then there will be something in the policy at
25 * position i *)
26definition is_jump' ≝
27  λx:preinstruction Identifier.
28  match x with
29  [ JC _ ⇒ True
30  | JNC _ ⇒ True
31  | JZ _ ⇒ True
32  | JNZ _ ⇒ True
33  | JB _ _ ⇒ True
34  | JNB _ _ ⇒ True
35  | JBC _ _ ⇒ True
36  | CJNE _ _ ⇒ True
37  | DJNZ _ _ ⇒ True
38  | _ ⇒ False
39  ].
40 
41definition is_jump ≝
42  λx:labelled_instruction.
43  let 〈label,instr〉 ≝ x in
44  match instr with
45  [ Instruction i   ⇒ is_jump' i
46  | Call _ ⇒ True
47  | Jmp _ ⇒ True
48  | _ ⇒ False
49  ].
50
51definition jump_in_policy ≝
52  λprefix:list labelled_instruction.λpolicy:jump_expansion_policy.
53  ∀i:ℕ.i < |prefix| →
54  (is_jump (nth i ? prefix 〈None ?, Comment []〉) ↔
55   ∃p:ℕ.∃a:ℕ.∃j:jump_length.
56     lookup_opt … (bitvector_of_nat 16 i) (\snd policy) = Some ? 〈p,a,j〉).
57
58definition labels_okay ≝
59  λlabels:label_map.λpolicy:jump_expansion_policy.
60  bvt_forall ?? (\snd policy) (λn.λx.
61   let 〈pc,addr_nat,j〉 ≝ x in
62   ∃id:Identifier.\snd (lookup_def … labels id 〈0,pc〉) = addr_nat
63  ).
64 
65(* Between two policies, jumps cannot decrease *)
66definition jmple: jump_length → jump_length → Prop ≝
67  λj1.λj2.
68  match j1 with
69  [ short_jump  ⇒
70    match j2 with
71    [ short_jump ⇒ False
72    | _          ⇒ True
73    ]
74  | medium_jump ⇒
75    match j2 with
76    [ long_jump ⇒ True
77    | _         ⇒ False
78    ]
79  | long_jump   ⇒ False
80  ].
81
82definition jmpleq: jump_length → jump_length → Prop ≝
83  λj1.λj2.jmple j1 j2 ∨ j1 = j2.
84 
85definition policy_increase: list labelled_instruction → jump_expansion_policy →
86  jump_expansion_policy → Prop ≝
87 λprogram.λop.λp.
88  (∀i:ℕ.i < |program| →
89    let 〈pc1,i1,oj〉 ≝ bvt_lookup ?? (bitvector_of_nat ? i) (\snd op) 〈0,0,short_jump〉 in
90    let 〈pc2,i2,j〉 ≝ bvt_lookup ?? (bitvector_of_nat ? i) (\snd p) 〈0,0,short_jump〉 in
91    jmpleq oj j
92  ).
93
94(* Policy safety *)
95definition policy_safe: jump_expansion_policy → Prop ≝
96 λpolicy.
97 bvt_forall ?? (\snd policy) (λn.λx.let 〈pc_nat,addr_nat,jmp_len〉 ≝ x in
98   match jmp_len with
99   [ short_jump  ⇒ if leb pc_nat addr_nat
100      then le (addr_nat - pc_nat) 126
101      else le (pc_nat - addr_nat) 129
102   | medium_jump ⇒   
103      let addr ≝ bitvector_of_nat 16 addr_nat in
104      let pc ≝ bitvector_of_nat 16 pc_nat in
105      let 〈fst_5_addr, rest_addr〉 ≝ split bool 5 11 addr in
106      let 〈fst_5_pc, rest_pc〉 ≝ split bool 5 11 pc in
107      eq_bv 5 fst_5_addr fst_5_pc = true
108   | long_jump   ⇒ True
109   ]
110 ).
111 
112(* Definitions and theorems for the jump_length type (itself defined in Assembly) *)
113definition max_length: jump_length → jump_length → jump_length ≝
114  λj1.λj2.
115  match j1 with
116  [ long_jump   ⇒ long_jump
117  | medium_jump ⇒
118    match j2 with
119    [ medium_jump ⇒ medium_jump
120    | _           ⇒ long_jump
121    ]
122  | short_jump  ⇒
123    match j2 with
124    [ short_jump ⇒ short_jump
125    | _          ⇒ long_jump
126    ]
127  ].
128
129lemma dec_jmple: ∀x,y:jump_length.jmple x y + ¬(jmple x y).
130 #x #y cases x cases y /3 by inl, inr, nmk, I/
131qed.
132 
133lemma jmpleq_max_length: ∀ol,nl.
134  jmpleq ol (max_length ol nl).
135 #ol #nl cases ol cases nl
136 /2 by or_introl, or_intror, I/
137qed.
138
139lemma dec_eq_jump_length: ∀a,b:jump_length.(a = b) + (a ≠ b).
140  #a #b cases a cases b /2/
141  %2 @nmk #H destruct (H)
142qed.
143
144(* Labels *)
145definition is_label ≝
146  λx:labelled_instruction.λl:Identifier.
147  let 〈lbl,instr〉 ≝ x in
148  match lbl with
149  [ Some l' ⇒ l' = l
150  | _       ⇒ False
151  ].
152
153lemma label_does_not_occur:
154  ∀i,p,l.
155  is_label (nth i ? p 〈None ?, Comment [ ]〉) l → does_not_occur l p = false.
156 #i #p #l generalize in match i; elim p
157 [ #i >nth_nil #H @⊥ @H
158 | #h #t #IH #i cases i -i
159   [ cases h #hi #hp cases hi
160     [ normalize #H @⊥ @H
161     | #l' #Heq whd in ⊢ (??%?); change with (eq_identifier ? l' l) in match (instruction_matches_identifier ??);
162       whd in Heq; >Heq
163       >eq_identifier_refl / by refl/
164     ]
165   | #i #H whd in match (does_not_occur ??);
166     whd in match (instruction_matches_identifier ??);
167     cases h #hi #hp cases hi normalize nodelta
168     [ @(IH i) @H
169     | #l' @eq_identifier_elim
170       [ normalize / by /
171       | normalize #_ @(IH i) @H
172       ]
173     ]
174   ]
175 ]
176qed.
177
178definition expand_relative_jump_internal_unsafe:
179  jump_length → ([[relative]] → preinstruction [[relative]]) → option (list instruction) ≝
180  λjmp_len,i.
181  match jmp_len with
182  [ short_jump ⇒ Some ? [ RealInstruction (i (RELATIVE (zero 8))) ]
183  | medium_jump ⇒ None …
184  | long_jump ⇒ Some ?
185    [ RealInstruction (i (RELATIVE (bitvector_of_nat ? 2)));
186      SJMP (RELATIVE (bitvector_of_nat ? 3)); (* LJMP size? *)
187      LJMP (ADDR16 (zero 16))
188    ]
189  ].
190 @I
191qed.
192
193definition expand_relative_jump_unsafe:
194  jump_length → preinstruction Identifier → option (list instruction) ≝
195  λjmp_len,i.
196  match i with
197  [ JC jmp ⇒ expand_relative_jump_internal_unsafe jmp_len (JC ?)
198  | JNC jmp ⇒ expand_relative_jump_internal_unsafe jmp_len (JNC ?)
199  | JB baddr jmp ⇒ expand_relative_jump_internal_unsafe jmp_len (JB ? baddr)
200  | JZ jmp ⇒ expand_relative_jump_internal_unsafe jmp_len (JZ ?)
201  | JNZ jmp ⇒ expand_relative_jump_internal_unsafe jmp_len (JNZ ?)
202  | JBC baddr jmp ⇒ expand_relative_jump_internal_unsafe jmp_len (JBC ? baddr)
203  | JNB baddr jmp ⇒ expand_relative_jump_internal_unsafe jmp_len (JNB ? baddr)
204  | CJNE addr jmp ⇒ expand_relative_jump_internal_unsafe jmp_len (CJNE ? addr)
205  | DJNZ addr jmp ⇒ expand_relative_jump_internal_unsafe jmp_len (DJNZ ? addr)
206  | ADD arg1 arg2 ⇒ Some … [ ADD ? arg1 arg2 ]
207  | ADDC arg1 arg2 ⇒ Some … [ ADDC ? arg1 arg2 ]
208  | SUBB arg1 arg2 ⇒ Some … [ SUBB ? arg1 arg2 ]
209  | INC arg ⇒ Some … [ INC ? arg ]
210  | DEC arg ⇒ Some … [ DEC ? arg ]
211  | MUL arg1 arg2 ⇒ Some … [ MUL ? arg1 arg2 ]
212  | DIV arg1 arg2 ⇒  Some … [ DIV ? arg1 arg2 ]
213  | DA arg ⇒ Some … [ DA ? arg ]
214  | ANL arg ⇒ Some … [ ANL ? arg ]
215  | ORL arg ⇒ Some … [ ORL ? arg ]
216  | XRL arg ⇒ Some … [ XRL ? arg ]
217  | CLR arg ⇒ Some … [ CLR ? arg ]
218  | CPL arg ⇒ Some … [ CPL ? arg ]
219  | RL arg ⇒ Some … [ RL ? arg ]
220  | RR arg ⇒ Some … [ RR ? arg ]
221  | RLC arg ⇒ Some … [ RLC ? arg ]
222  | RRC arg ⇒ Some … [ RRC ? arg ]
223  | SWAP arg ⇒ Some … [ SWAP ? arg ]
224  | MOV arg ⇒ Some … [ MOV ? arg ]
225  | MOVX arg ⇒ Some … [ MOVX ? arg ]
226  | SETB arg ⇒ Some … [ SETB ? arg ]
227  | PUSH arg ⇒ Some … [ PUSH ? arg ]
228  | POP arg ⇒ Some … [ POP ? arg ]
229  | XCH arg1 arg2 ⇒ Some … [ XCH ? arg1 arg2 ]
230  | XCHD arg1 arg2 ⇒ Some … [ XCHD ? arg1 arg2 ]
231  | RET ⇒ Some … [ RET ? ]
232  | RETI ⇒ Some … [ RETI ? ]
233  | NOP ⇒ Some … [ RealInstruction (NOP ?) ]
234  ].
235
236definition expand_pseudo_instruction_unsafe:
237 jump_length → pseudo_instruction → option (list instruction) ≝
238  λjmp_len.
239  λi.
240  match i with
241  [ Cost cost ⇒ Some ? [ ]
242  | Comment comment ⇒ Some ? [ ]
243  | Call call ⇒
244    match jmp_len with
245    [ short_jump ⇒ None ?
246    | medium_jump ⇒ Some ? [ ACALL (ADDR11 (zero 11)) ]
247    | long_jump ⇒ Some ? [ LCALL (ADDR16 (zero 16)) ]
248    ]
249  | Mov d trgt ⇒
250      Some ? [ RealInstruction (MOV ? (inl ? ? (inl ? ? (inr ? ? 〈DPTR, DATA16 (zero 16)〉))))]
251  | Instruction instr ⇒ expand_relative_jump_unsafe jmp_len instr
252  | Jmp jmp ⇒
253    match jmp_len with
254    [ short_jump ⇒ Some ? [ SJMP (RELATIVE (zero 8)) ]
255    | medium_jump ⇒ Some ? ([ AJMP (ADDR11 (zero 11)) ])
256    | long_jump ⇒ Some ? [ LJMP (ADDR16 (zero 16)) ]
257    ]
258  ].
259 @I
260qed.
261
262definition instruction_size: (* ℕ → *) jump_length → pseudo_instruction → ℕ ≝
263  λjmp_len.λinstr.
264  let ilist ≝ expand_pseudo_instruction_unsafe jmp_len instr in
265  let bv: list (BitVector 8) ≝ match ilist with
266    [ None   ⇒ (* this shouldn't happen *) [ ]
267    | Some l ⇒ flatten … (map … assembly1 l)
268    ] in
269  |bv|.
270 
271definition policy_isize_sum ≝
272  λprefix:list labelled_instruction.λpolicy:jump_expansion_policy.
273  (\fst policy) = foldl_strong (option Identifier × pseudo_instruction)
274  (λacc.ℕ)
275  prefix
276  (λhd.λx.λtl.λp.λacc.
277    let 〈i1,i2,jl〉 ≝ bvt_lookup … (bitvector_of_nat ? (|hd|)) (\snd policy) 〈0,0,short_jump〉 in
278    acc + (instruction_size jl (\snd x)))
279  0.
280
281(* The function that creates the label-to-address map *)
282definition create_label_map: ∀program:list labelled_instruction.
283  ∀policy:jump_expansion_policy.
284  (Σlabels:label_map.
285    ∀i:ℕ.lt i (|program|) →
286    ∀l.occurs_exactly_once l program →
287    is_label (nth i ? program 〈None ?, Comment [ ]〉) l →
288    ∃a.lookup … labels l = Some ? 〈i,a〉
289  ) ≝
290  λprogram.λpolicy.
291  let 〈final_pc, final_labels〉 ≝
292    foldl_strong (option Identifier × pseudo_instruction)
293    (λprefix.ℕ × (Σlabels.
294      ∀i:ℕ.lt i (|prefix|) →
295      ∀l.occurs_exactly_once l prefix →
296      is_label (nth i ? prefix 〈None ?, Comment [ ]〉) l →
297      ∃a.lookup … labels l = Some ? 〈i,a〉)
298    )
299    program
300    (λprefix.λx.λtl.λprf.λacc.
301     let 〈pc,labels〉 ≝ acc in
302     let 〈label,instr〉 ≝ x in
303       let new_labels ≝
304       match label with
305       [ None   ⇒ labels
306       | Some l ⇒ add … labels l 〈|prefix|, pc〉
307       ] in
308     let 〈i1,i2,jmp_len〉 ≝
309       bvt_lookup ?? (bitvector_of_nat 16 (|prefix|)) (\snd policy) 〈0,0,short_jump〉 in
310       〈pc + (instruction_size jmp_len instr), new_labels〉
311    ) 〈0, empty_map …〉 in
312    final_labels.
313[#i >append_length >commutative_plus #Hi normalize in Hi; cases (le_to_or_lt_eq … Hi) -Hi;
314  [ #Hi #l normalize nodelta; cases label normalize nodelta
315    [ >occurs_exactly_once_None #Hocc >(nth_append_first ? ? prefix ? ? (le_S_S_to_le ? ? Hi)) #Hl
316      lapply (pi2 … labels) #Hacc elim (Hacc i (le_S_S_to_le … Hi) l Hocc Hl) #addr #Haddr 
317      % [ @addr | @Haddr ]
318    | #l' #Hocc #Hl lapply (occurs_exactly_once_Some_stronger … Hocc) -Hocc;
319      @eq_identifier_elim #Heq #Hocc
320      [ normalize in Hocc;
321        >(nth_append_first ? ? prefix ? ? (le_S_S_to_le … Hi)) in Hl; #Hl 
322        @⊥ @(absurd … Hocc)
323      | normalize nodelta lapply (pi2 … labels) #Hacc elim (Hacc i (le_S_S_to_le … Hi) l Hocc ?)
324        [ #addr #Haddr % [ @addr | <Haddr @lookup_add_miss /2/ ]
325        | >(nth_append_first ? ? prefix ? ? (le_S_S_to_le … Hi)) in Hl; / by /
326        ]
327      ]
328      >(label_does_not_occur i … Hl) normalize nodelta @nmk / by /
329    ]
330  | #Hi #l #Hocc >(injective_S … Hi) >nth_append_second
331    [ <minus_n_n #Hl normalize in Hl; normalize nodelta cases label in Hl;
332      [ normalize nodelta #H @⊥ @H
333      | #l' normalize nodelta #Heq % [ @pc | <Heq normalize nodelta @lookup_add_hit ]
334      ]
335    | @le_n
336    ]
337  ]
338| #i #Hi #l #Hl @⊥ @Hl
339]
340qed.
341
342definition select_reljump_length: label_map → ℕ → Identifier → ℕ ×jump_length ≝
343  λlabels.λpc.λlbl.
344  let 〈n, addr〉 ≝ lookup_def … labels lbl 〈0, pc〉 in
345  if leb pc addr (* forward jump *)
346  then if leb (addr - pc) 126
347       then 〈addr, short_jump〉
348       else 〈addr, long_jump〉
349  else if leb (pc - addr) 129
350       then 〈addr, short_jump〉
351       else 〈addr, long_jump〉.
352
353definition select_call_length: label_map → ℕ → Identifier → ℕ × jump_length ≝
354  λlabels.λpc_nat.λlbl.
355  let pc ≝ bitvector_of_nat 16 pc_nat in
356  let addr_nat ≝ (\snd (lookup_def ? ? labels lbl 〈0, pc_nat〉)) in
357  let addr ≝ bitvector_of_nat 16 addr_nat in
358  let 〈fst_5_addr, rest_addr〉 ≝ split ? 5 11 addr in
359  let 〈fst_5_pc, rest_pc〉 ≝ split ? 5 11 pc in
360  if eq_bv ? fst_5_addr fst_5_pc
361  then 〈addr_nat, medium_jump〉
362  else 〈addr_nat, long_jump〉.
363 
364definition select_jump_length: label_map → ℕ → Identifier → ℕ × jump_length ≝
365  λlabels.λpc.λlbl.
366  let 〈n, addr〉 ≝ lookup_def … labels lbl 〈0, pc〉 in
367  if leb pc addr
368  then if leb (addr - pc) 126
369       then 〈addr, short_jump〉
370       else select_call_length labels pc lbl
371  else if leb (pc - addr) 129
372       then 〈addr, short_jump〉
373       else select_call_length labels pc lbl.
374 
375definition jump_expansion_step_instruction: label_map → ℕ →
376  preinstruction Identifier → option (ℕ × jump_length) ≝
377  λlabels.λpc.λi.
378  match i with
379  [ JC j     ⇒ Some ? (select_reljump_length labels pc j)
380  | JNC j    ⇒ Some ? (select_reljump_length labels pc j)
381  | JZ j     ⇒ Some ? (select_reljump_length labels pc j)
382  | JNZ j    ⇒ Some ? (select_reljump_length labels pc j)
383  | JB _ j   ⇒ Some ? (select_reljump_length labels pc j)
384  | JBC _ j  ⇒ Some ? (select_reljump_length labels pc j)
385  | JNB _ j  ⇒ Some ? (select_reljump_length labels pc j)
386  | CJNE _ j ⇒ Some ? (select_reljump_length labels pc j)
387  | DJNZ _ j ⇒ Some ? (select_reljump_length labels pc j)
388  | _        ⇒ None ?
389  ].
390
391lemma dec_is_jump: ∀x.(is_jump x) + (¬is_jump x).
392#x cases x #l #i cases i
393[#id cases id
394 [1,2,3,6,7,33,34:
395  #x #y %2 whd in match (is_jump ?); /2 by nmk/
396 |4,5,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32:
397  #x %2 whd in match (is_jump ?); /2 by nmk/
398 |35,36,37: %2 whd in match (is_jump ?); /2 by nmk/
399 |9,10,14,15: #x %1 / by I/
400 |11,12,13,16,17: #x #y %1 / by I/
401 ]
402|2,3: #x %2 /2 by nmk/
403|4,5: #x %1 / by I/
404|6: #x #y %2 /2 by nmk/
405]
406qed.
407
408lemma jump_not_in_policy: ∀prefix:list labelled_instruction.
409 ∀policy:(Σp:jump_expansion_policy.
410 out_of_program_none prefix p ∧ jump_in_policy prefix p).
411  ∀i:ℕ.i < |prefix| →
412  iff (¬is_jump (nth i ? prefix 〈None ?, Comment []〉))
413  (lookup_opt … (bitvector_of_nat 16 i) (\snd policy) = None ?).
414 #prefix #policy #i #Hi @conj
415[ #Hnotjmp lapply (refl ? (lookup_opt … (bitvector_of_nat 16 i) (\snd policy)))
416  cases (lookup_opt … (bitvector_of_nat 16 i) (\snd policy)) in ⊢ (???% → ?);
417  [ #H @H
418  | #x cases x -x #x cases x -x #x #y #z #H @⊥ @(absurd ? ? Hnotjmp) @(proj2 ?? (proj2 ?? (pi2 ?? policy) i Hi))
419    @(ex_intro ?? x (ex_intro ?? y (ex_intro ?? z H)))
420  ]
421| #Hnone @nmk #Hj lapply (proj1 ?? (proj2 ?? (pi2 ?? policy) i Hi) Hj)
422  #H elim H -H; #x #H elim H -H; #y #H elim H -H #z #H >H in Hnone; #abs destruct (abs)
423
424qed.
425
426(* these two obviously belong somewhere else *) 
427lemma pi1_eq: ∀A:Type[0].∀P:A->Prop.∀s1:Σa1:A.P a1.∀s2:Σa2:A.P a2.
428  s1 = s2 → (pi1 ?? s1) = (pi1 ?? s2).
429 #A #P #s1 #s2 / by /
430qed.
431
432lemma Some_eq:
433 ∀T:Type[0].∀x,y:T. Some T x = Some T y → x = y.
434 #T #x #y #H @option_destruct_Some @H
435qed.
436
437(* The first step of the jump expansion: everything to short.
438 * The third condition of the dependent type implies jump_in_policy;
439 * I've left it in for convenience of type-checking. *)
440definition jump_expansion_start:
441  ∀program:(Σl:list labelled_instruction.|l| < 2^16).
442  Σpolicy:jump_expansion_policy.
443    out_of_program_none program policy ∧
444    jump_in_policy program policy ∧
445    ∀i.i < |program| → is_jump (nth i ? program 〈None ?, Comment []〉) →
446     lookup_opt … (bitvector_of_nat 16 i) (\snd policy) = Some ? 〈0,0,short_jump〉 ≝
447  λprogram.
448  foldl_strong (option Identifier × pseudo_instruction)
449  (λprefix.Σpolicy:jump_expansion_policy.
450    out_of_program_none prefix policy ∧
451    jump_in_policy prefix policy ∧
452    ∀i.i < |prefix| → is_jump (nth i ? prefix 〈None ?, Comment []〉) →
453      lookup_opt … (bitvector_of_nat 16 i) (\snd policy) = Some ? 〈0,0,short_jump〉)
454  program
455  (λprefix.λx.λtl.λprf.λp.
456   let 〈pc,policy〉 ≝ p in
457   let 〈label,instr〉 ≝ x in
458   〈pc + instruction_size short_jump instr,match instr with
459   [ Instruction i ⇒ match i with
460     [ JC _ ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
461     | JNC _ ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
462     | JZ _ ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
463     | JNZ _ ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
464     | JB _ _ ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
465     | JNB _ _ ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
466     | JBC _ _ ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
467     | CJNE _ _ ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
468     | DJNZ _ _ ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
469     | _ ⇒ policy
470     ]
471   | Call c ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
472   | Jmp j  ⇒ bvt_insert … (bitvector_of_nat 16 (|prefix|)) 〈0,0,short_jump〉 policy
473   | _      ⇒ policy
474   ]〉
475  ) 〈0, Stub ? ?〉.
476[ @conj
477  [ @conj
478    #i >append_length <commutative_plus #Hi normalize in Hi;
479    [ #Hi2 cases (le_to_or_lt_eq … Hi) -Hi #Hi
480      cases p -p #p cases p -p #pc #p #Hp cases x -x #l #pi cases pi
481      [1,7: #id cases id normalize nodelta
482        [1,2,3,4,5,6,7,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37:
483          [1,2,3,6,7,24,25: #x #y
484          |4,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23: #x]
485          @(proj1 ?? (proj1 ?? Hp) i ? Hi2) @le_S_to_le @le_S_to_le @Hi
486        |38,39,40,41,42,43,44,45,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74:
487          [1,2,3,6,7,24,25: #x #y
488          |4,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23: #x]
489          <Hi @(proj1 ?? (proj1 ?? Hp) (S (|prefix|)) (le_S ?? (le_n (|prefix|))) ?)
490          >Hi @Hi2
491        |9,10,11,12,13,14,15,16,17:
492          [1,2,6,7: #x |3,4,5,8,9: #x #id] >lookup_opt_insert_miss
493          [2,4,6,8,10,12,14,16,18: @bitvector_of_nat_abs
494            [1,4,7,10,13,16,19,22,25: @Hi2
495            |2,5,8,11,14,17,20,23,26: @(transitive_lt … Hi2) @le_S_to_le @Hi
496            |3,6,9,12,15,18,21,24,27: @sym_neq @lt_to_not_eq @le_S_to_le @Hi
497            ]
498          |1,3,5,7,9,11,13,15,17:
499            @(proj1 ?? (proj1 ?? Hp) i ? Hi2) @le_S_to_le @le_S_to_le @Hi
500          ]
501        |46,47,48,49,50,51,52,53,54:
502          [1,2,6,7: #x |3,4,5,8,9: #x #id] >lookup_opt_insert_miss
503          [2,4,6,8,10,12,14,16,18: @bitvector_of_nat_abs
504            [1,4,7,10,13,16,19,22,25: @Hi2
505            |2,5,8,11,14,17,20,23,26: @(transitive_lt … Hi2) <Hi @le_n
506            |3,6,9,12,15,18,21,24,27: @sym_neq @lt_to_not_eq <Hi @le_n
507            ]
508          |1,3,5,7,9,11,13,15,17:
509            @(proj1 ?? (proj1 ?? Hp) i ? Hi2) <Hi @le_S @le_n
510          ]
511        ]
512      |2,3,6,8,9,12: [3,6: #w] #z normalize nodelta
513        [1,3,4: @(proj1 ?? (proj1 ?? Hp) i ? Hi2) @le_S_to_le @le_S_to_le @Hi
514        |2,5,6:
515          <Hi @(proj1 ?? (proj1 ?? Hp) (S (|prefix|)) (le_S ?? (le_n (|prefix|))) ?)
516          >Hi @Hi2
517        ]
518      |4,5,10,11: #dst normalize nodelta >lookup_opt_insert_miss
519        [2,4,6,8: @bitvector_of_nat_abs
520          [1,4,7,10: @Hi2
521          |2,5: @(transitive_lt … Hi2) @le_S_to_le @Hi
522          |8,11: @(transitive_lt … Hi2) <Hi @le_n
523          |3,6: @sym_neq @lt_to_not_eq @le_S_to_le @Hi
524          |9,12: @sym_neq @lt_to_not_eq <Hi @le_n
525          ]         
526        |1,3: @(proj1 ?? (proj1 ?? Hp) i ? Hi2) @le_S_to_le @le_S_to_le @Hi
527        |5,7: @(proj1 ?? (proj1 ?? Hp) i ? Hi2) <Hi @le_S @le_n
528        ]
529      ]
530    | cases (le_to_or_lt_eq … Hi) -Hi #Hi
531      [ >(nth_append_first ?? prefix ?? (le_S_S_to_le … Hi)) @conj
532        [ #Hj @(ex_intro ?? 0 (ex_intro ?? 0 (ex_intro ?? short_jump ?)))
533          cases p -p #p cases p #pc #pol #Hp cases x #l #ins cases ins normalize nodelta
534          [1: #pi cases pi normalize nodelta
535            [1,2,3,6,7,33,34: #x #y
536            |4,5,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32: #x
537            |9,10,11,12,13,14,15,16,17:
538              [1,2,6,7: #x | 3,4,5,8,9: #x #id] >lookup_opt_insert_miss
539              [2,4,6,8,10,12,14,16,18: @bitvector_of_nat_abs
540               [1,4,7,10,13,16,19,22,25: @(transitive_lt … (pi2 ?? program)) >prf
541                 >append_length <plus_n_Sm @le_S_to_le @(transitive_le … Hi)
542                 @le_S_S_to_le @le_plus_n_r
543               |2,5,8,11,14,17,20,23,26: @(transitive_lt … (pi2 ?? program)) >prf
544                 >append_length <plus_n_Sm @le_S_S_to_le @le_plus_n_r
545               |3,6,9,12,15,18,21,24,27: @lt_to_not_eq @(le_S_S_to_le … Hi)
546               ]
547              ]
548            ]
549          |2,3: #x
550          |4,5: #id >lookup_opt_insert_miss
551            [2,4: @bitvector_of_nat_abs
552              [1,4: @(transitive_lt … (pi2 ?? program)) >prf
553                 >append_length <plus_n_Sm @le_S_to_le @(transitive_le … Hi)
554                 @le_S_S_to_le @le_plus_n_r
555              |2,5: @(transitive_lt … (pi2 ?? program)) >prf
556                 >append_length <plus_n_Sm @le_S_S_to_le @le_plus_n_r
557              |3,6: @lt_to_not_eq @(le_S_S_to_le … Hi)
558              ]
559            ]
560          |6: #x #id
561          ]
562          @((proj2 ?? Hp) i (le_S_S_to_le … Hi) Hj)
563        | #H @(proj2 ?? (proj2 ?? (proj1 ?? (pi2 ?? p)) i ?))
564          [ @(le_S_S_to_le … Hi)
565          | cases p in H; -p #p cases p #pc #pol #Hp cases x #l #ins cases ins normalize nodelta
566            [1: #id cases id
567              [1,2,3,4,5,6,7,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37:
568                [1,2,3,6,7,24,25: #x #y
569                |4,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23: #x]
570                normalize nodelta / by /
571              |9,10,11,12,13,14,15,16,17: [1,2,6,7: #x |3,4,5,8,9: #x #id]
572                normalize nodelta >lookup_opt_insert_miss
573                [1,3,5,7,9,11,13,15,17: / by /
574                |2,4,6,8,10,12,14,16,18: @bitvector_of_nat_abs
575                  [1,4,7,10,13,16,19,22,25: @(transitive_lt … (pi2 ?? program)) >prf
576                    >append_length <plus_n_Sm @le_S_to_le @(transitive_le … Hi)
577                    @le_S_S_to_le @le_plus_n_r
578                  |2,5,8,11,14,17,20,23,26: @(transitive_lt … (pi2 ?? program)) >prf
579                    >append_length <plus_n_Sm @le_S_S_to_le @le_plus_n_r 
580                  |3,6,9,12,15,18,21,24,27: @lt_to_not_eq @(le_S_S_to_le … Hi)
581                  ]
582                ]
583              ]
584            |2,3: #x / by /
585            |4,5: #id >lookup_opt_insert_miss
586              [2,4: @bitvector_of_nat_abs
587                [1,4: @(transitive_lt … (pi2 ?? program)) >prf
588                   >append_length <plus_n_Sm @le_S_to_le @(transitive_le … Hi)
589                   @le_S_S_to_le @le_plus_n_r
590                |2,5: @(transitive_lt … (pi2 ?? program)) >prf
591                   >append_length <plus_n_Sm @le_S_S_to_le @le_plus_n_r
592                |3,6: @lt_to_not_eq @(le_S_S_to_le … Hi)
593                ]
594              |1,3: / by /
595              ]
596            |6: #x #id / by /
597            ]
598          ]
599        ]
600      | >(injective_S … Hi) >(nth_append_second ?? prefix ?? (le_n (|prefix|)))
601        <minus_n_n whd in match (nth ????);
602        cases x #l #ins cases ins
603        [1: #pi cases pi
604          [1,2,3,4,5,6,7,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37:
605            [1,2,3,6,7,24,25: #x #y
606            |4,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23: #x]
607            @conj
608            [1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55:
609              #H @⊥ @H
610            |2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56:
611              cases p -p #p cases p -p #pc #pol #Hp #H elim H -H #p #H elim H -H #a #H elim H -H #j
612              normalize nodelta >(proj1 ?? (proj1 ?? Hp) (|prefix|) (le_n (|prefix|)) ?)
613              [1,3,5,7,9,11,13,15,17,19,21,23,25,27,29,31,33,35,37,39,41,43,45,47,49,51,53,55:
614                #H destruct (H)
615              |2,4,6,8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56:
616                @(transitive_lt … (pi2 ?? program)) >prf >append_length <plus_n_Sm
617                @le_S_S_to_le @le_plus_n_r
618              ]
619            ]
620          |9,10,11,12,13,14,15,16,17: [1,2,6,7: #x | 3,4,5,8,9: #x #id]
621            @conj
622            [1,3,5,7,9,11,13,15,17:
623              #_ @(ex_intro ?? 0 (ex_intro ?? 0 (ex_intro ?? short_jump ?)))
624              cases p -p #p cases p -p #pc #pol #Hp @lookup_opt_insert_hit
625            |2,4,6,8,10,12,14,16,18:
626              #_ / by I/
627            ]
628          ]
629        |2,3,6: #x [3: #id] @conj
630          [1,3,5: #H @⊥ @H
631          |2,4,6:
632            cases p -p #p cases p -p #pc #pol #Hp #H elim H -H #p #H elim H -H #a #H elim H -H #j
633            normalize nodelta >(proj1 ?? (proj1 ?? Hp) (|prefix|) (le_n (|prefix|)) ?)
634            [1,3,5: #H destruct (H)
635            |2,4,6: @(transitive_lt … (pi2 ?? program)) >prf >append_length <plus_n_Sm
636              @le_S_S_to_le @le_plus_n_r
637            ]
638          ]
639        |4,5: #x @conj
640          [1,3: #_ @(ex_intro ?? 0 (ex_intro ?? 0 (ex_intro ?? short_jump ?)))
641            cases p -p #p cases p -p #pc #pol #Hp @lookup_opt_insert_hit
642          |2,4: #_ / by I/
643        ]
644      ]
645    ]
646  ]
647| #i >append_length <commutative_plus #Hi normalize in Hi;
648  elim (le_to_or_lt_eq … Hi) -Hi #Hi
649  [ >(nth_append_first ?? prefix ?? (le_S_S_to_le … Hi)) #H
650    cases p -p #p cases p #pc #pol #Hp cases x #l #ins cases ins normalize nodelta
651    [1: #pi cases pi
652      [1,2,3,4,5,6,7,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37:
653        [1,2,3,6,7,24,25: #x #y
654        |4,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23: #x]
655        normalize nodelta
656        @((proj2 ?? Hp) i (le_S_S_to_le … Hi) H)
657      |9,10,11,12,13,14,15,16,17: [1,2,6,7: #x | 3,4,5,8,9: #x #id]
658        normalize nodelta >lookup_opt_insert_miss
659        [1,3,5,7,9,11,13,15,17: @((proj2 ?? Hp) i (le_S_S_to_le … Hi) H)
660        |2,4,6,8,10,12,14,16,18,20: @bitvector_of_nat_abs
661          [1,4,7,10,13,16,19,22,25: @(transitive_lt … (pi2 ?? program)) >prf
662            >append_length <plus_n_Sm @le_S_to_le @(transitive_le … Hi)
663            @le_S_S_to_le @le_plus_n_r
664          |2,5,8,11,14,17,20,23,26: @(transitive_lt … (pi2 ?? program)) >prf
665            >append_length <plus_n_Sm @le_S_S_to_le @le_plus_n_r
666          |3,6,9,12,15,18,21,24,27: @lt_to_not_eq @(le_S_S_to_le … Hi)
667          ]
668        ]
669      ]
670    |2,3,6: #x [3: #id]
671      normalize nodelta @((proj2 ?? Hp) i (le_S_S_to_le … Hi) H)
672    |4,5: #x >lookup_opt_insert_miss
673      [1,3: @((proj2 ?? Hp) i (le_S_S_to_le … Hi) H)
674      |2,4: @bitvector_of_nat_abs
675        [1,4: @(transitive_lt … (pi2 ?? program)) >prf
676          >append_length <plus_n_Sm @le_S_to_le @(transitive_le … Hi)
677          @le_S_S_to_le @le_plus_n_r
678        |2,5: @(transitive_lt … (pi2 ?? program)) >prf
679          >append_length <plus_n_Sm @le_S_S_to_le @le_plus_n_r
680        |3,6: @lt_to_not_eq @(le_S_S_to_le … Hi)
681        ]
682      ]
683    ]
684  | >(injective_S … Hi) >(nth_append_second ?? prefix ?? (le_n (|prefix|)))
685    <minus_n_n whd in match (nth ????); cases x #l #ins cases ins
686    [1: #pi cases pi
687      [1,2,3,4,5,6,7,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37:
688        [1,2,3,6,7,24,25: #x #y
689        |4,5,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23: #x]
690        #H @⊥ @H
691      |9,10,11,12,13,14,15,16,17: [1,2,6,7: #x | 3,4,5,8,9: #x #id]
692        #_ cases p -p #p cases p -p #pc #pol #Hp >lookup_opt_insert_hit / by /
693      ]
694    |2,3,6: #x [3: #id] #H @⊥ @H
695    |4,5: #id #_ cases p -p #p cases p -p #pc #pol #Hp >lookup_opt_insert_hit / by /
696    ]
697  ]
698]
699| @conj
700  [ @conj
701    [ #i #_ #Hi2 / by refl/
702    | #i #_ @conj
703      [ >nth_nil #H @⊥ @H
704      | #H elim H -H #p #H elim H -H #a #H elim H -H #j #H normalize in H; destruct (H)
705      ]
706    ]
707  | #i #Hi >nth_nil #H @⊥ @H
708  ]
709]
710qed.
711
712definition policy_equal_int ≝
713  λprogram:list labelled_instruction.λp1,p2:jump_expansion_policy.
714  ∀n:ℕ.n < |program| →
715    let 〈pc1,i1,j1〉 ≝ bvt_lookup … (bitvector_of_nat 16 n) (\snd p1) 〈0,0,short_jump〉 in
716    let 〈pc2,i2,j2〉 ≝ bvt_lookup … (bitvector_of_nat 16 n) (\snd p2) 〈0,0,short_jump〉 in
717    j1 = j2.
718   
719definition nec_plus_ultra ≝
720  λprogram:list labelled_instruction.λp:jump_expansion_policy.
721  ¬(∀i.i < |program| → \snd (bvt_lookup … (bitvector_of_nat 16 i) (\snd p) 〈0,0,short_jump〉) = long_jump).
722 
723lemma geb_to_leb: ∀a,b:ℕ.geb a b = leb b a.
724  #a #b / by refl/
725qed.
726
727(* One step in the search for a jump expansion fixpoint. *)
728definition jump_expansion_step: ∀program:(Σl:list labelled_instruction.|l| < 2^16).
729  ∀labels:(Σlm:label_map.∀i:ℕ.lt i (|program|) →
730    ∀l.occurs_exactly_once l program →
731    is_label (nth i ? program 〈None ?, Comment [ ]〉) l →
732    ∃a.lookup … lm l = Some ? 〈i,a〉).
733  ∀old_policy:(Σpolicy:jump_expansion_policy.
734    out_of_program_none program policy ∧ jump_in_policy program policy ∧ (\fst policy < 2^16) ∧
735    policy_isize_sum program policy).
736  (Σx:bool × (option jump_expansion_policy).
737    let 〈ch,y〉 ≝ x in
738    match y with
739    [ None ⇒ nec_plus_ultra program old_policy
740    | Some p ⇒ out_of_program_none program p ∧ labels_okay labels p ∧
741        jump_in_policy program p ∧
742        policy_increase program old_policy p ∧ policy_safe p ∧
743        (ch = false → policy_equal_int program old_policy p (*sic!*)) ∧
744        policy_isize_sum program p ∧ \fst p < 2^16
745    ])
746    ≝
747  λprogram.λlabels.λold_policy.
748  let 〈final_changed, final_policy〉 ≝
749    foldl_strong (option Identifier × pseudo_instruction)
750    (λprefix.Σx:bool × jump_expansion_policy.
751        let 〈changed,policy〉 ≝ x in
752        out_of_program_none prefix policy ∧ labels_okay labels policy ∧
753        jump_in_policy prefix policy ∧
754        policy_increase prefix old_policy policy ∧
755        policy_safe policy ∧
756        (changed = false → policy_equal_int prefix old_policy policy) ∧
757        policy_isize_sum prefix policy)
758    program
759    (λprefix.λx.λtl.λprf.λacc.
760      let 〈changed, pol〉 ≝ acc in
761      (* let 〈pc,pol〉 ≝ p in *)
762      let 〈label,instr〉 ≝ x in
763      let add_instr ≝
764        match instr with
765        [ Instruction i ⇒ jump_expansion_step_instruction labels (\fst pol) i
766        | Call c        ⇒ Some ? (select_call_length labels (\fst pol) c)
767        | Jmp j         ⇒ Some ? (select_jump_length labels (\fst pol) j)
768        | _             ⇒ None ?
769        ] in
770      let old_length ≝ \snd (bvt_lookup … (bitvector_of_nat 16 (|prefix|)) (\snd old_policy) 〈0,0,short_jump〉) in
771      match add_instr with
772      [ None    ⇒ (* i.e. it's not a jump *)
773        let isize ≝ instruction_size short_jump instr in
774        〈changed, 〈(\fst pol) + isize, (\snd pol)〉〉
775      | Some z ⇒ let 〈addr,ai〉 ≝ z in
776        let new_length ≝ max_length old_length ai in
777        let isize ≝ instruction_size new_length instr in
778        〈match dec_eq_jump_length new_length old_length with
779         [ inl _ ⇒ changed
780         | inr _ ⇒ true], 〈(\fst pol) + isize,
781         insert … (bitvector_of_nat 16 (|prefix|)) 〈(\fst pol), addr, new_length〉 (\snd pol)〉〉
782      ]
783    ) 〈false, 〈0, Stub ? ?〉〉 in
784    if geb (\fst final_policy) 2^16 then
785      〈final_changed,None ?〉
786    else
787      〈final_changed,Some ? final_policy〉.
788[ @pair_elim #fch #x #Heq <(pair_eq2 ?????? Heq) normalize nodelta
789  @nmk #Hfull lapply p generalize in match (foldl_strong ?????); * #x #H #H2
790  >H2 in H; normalize nodelta -H2 -x #H
791  @(absurd ((\fst final_policy) ≥ 2^16))
792  [ @leb_true_to_le <geb_to_leb @p1
793  | @lt_to_not_le @(le_to_lt_to_lt … (proj2 ?? (proj1 ?? (pi2 ?? old_policy))))
794    >(proj2 ?? H) >(proj2 ?? (pi2 ?? old_policy))
795    cases daemon (* XXX *)
796  ]
797| normalize nodelta lapply p generalize in match (foldl_strong ?????); * #x #H #H2
798  >H2 in H; normalize nodelta #H @conj
799  [ @H
800  | @not_le_to_lt @leb_false_to_not_le <geb_to_leb @p1
801  ]
802| lapply (pi2 ?? acc) >p #Hpolicy normalize nodelta in Hpolicy;
803  cases (dec_eq_jump_length new_length old_length) #Hlength normalize nodelta
804  @conj [1,3: @conj [1,3: @conj [1,3: @conj [1,3: @conj [1,3: @conj
805[1,3: (* out_of_policy_none *)
806  #i >append_length <commutative_plus #Hi normalize in Hi;
807  #Hi2 >lookup_opt_insert_miss
808  [1,3: @(proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy))))) i (le_S_to_le … Hi)) @Hi2
809  |2,4: >eq_bv_sym @bitvector_of_nat_abs
810    [1,4: @(transitive_lt … (pi2 ?? program)) >prf >append_length normalize <plus_n_Sm
811      @le_S_S @le_plus_n_r
812    |2,5: @Hi2
813    |3,6: @lt_to_not_eq @Hi
814    ]
815  ]
816|2,4: (* labels_okay *)
817  @lookup_forall #i cases i -i #i cases i -i #p #a #j #n #Hl
818  elim (insert_lookup_opt ?? 〈p,a,j〉 ???? Hl) -Hl #Hl
819  [1,3: elim (forall_lookup … (proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy)))))) ? n Hl)
820    #i #Hi @(ex_intro ?? i Hi)
821  |2,4: normalize nodelta normalize nodelta in p2; cases instr in p2;
822    [2,3,8,9: #x #abs normalize nodelta in abs; lapply (jmeq_to_eq ??? abs) #H destruct (H)
823    |6,12: #x #y #abs normalize nodelta in abs; lapply (jmeq_to_eq ??? abs) #H destruct (H)
824    |1,7: #pi cases pi
825      [35,36,37,72,73,74: #abs normalize in abs; lapply (jmeq_to_eq ??? abs) #H destruct (H)
826      |1,2,3,6,7,33,34,38,39,40,43,44,70,71:
827        #x #y #abs normalize in abs; lapply (jmeq_to_eq ??? abs) #H destruct (H)
828      |4,5,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,41,42,45,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69:
829        #x #abs normalize in abs;lapply (jmeq_to_eq ??? abs) #H destruct (H)
830      |9,10,14,15,46,47,51,52:
831        #id normalize nodelta whd in match (jump_expansion_step_instruction ???);
832        whd in match (select_reljump_length ???); >p3
833        lapply (refl ? (lookup_def ?? (pi1 ?? labels) id 〈0,\fst pol〉))
834        cases (lookup_def ?? labels id 〈0,\fst pol〉) in ⊢ (???% → %); #q1 #q2
835        normalize nodelta #H
836        >(pair_eq1 ?????? (pair_eq1 ?????? (proj2 ?? Hl)))
837        >(pair_eq2 ?????? (pair_eq1 ?????? (proj2 ?? Hl))) lapply (refl ? (leb (\fst pol) q2))
838        cases (leb (\fst pol) q2) in ⊢ (???% → %); #Hle1
839        [1,3,5,7,9,11,13,15: lapply (refl ? (leb (q2-\fst pol) 126)) cases (leb (q2-\fst pol) 126) in ⊢ (???% → %);
840        |2,4,6,8,10,12,14,16: lapply (refl ? (leb (\fst pol-q2) 129)) cases (leb (\fst pol-q2) 129) in ⊢ (???% → %);
841        ]
842        #Hle2 normalize nodelta #Hli @(ex_intro ?? id) >H
843        <(pair_eq1 ?????? (Some_eq ??? Hli)) @refl
844      |11,12,13,16,17,48,49,50,53,54:
845        #x #id normalize nodelta whd in match (jump_expansion_step_instruction ???);
846        whd in match (select_reljump_length ???); >p3
847        lapply (refl ? (lookup_def ?? labels id 〈0,\fst pol〉))
848        cases (lookup_def ?? labels id 〈0,\fst pol〉) in ⊢ (???% → %); #q1 #q2
849        normalize nodelta #H
850        >(pair_eq1 ?????? (pair_eq1 ?????? (proj2 ?? Hl)))
851        >(pair_eq2 ?????? (pair_eq1 ?????? (proj2 ?? Hl))) lapply (refl ? (leb (\fst pol) q2))
852        cases (leb (\fst pol) q2) in ⊢ (???% → %); #Hle1
853        [1,3,5,7,9,11,13,15,17,19: lapply (refl ? (leb (q2-\fst pol) 126)) cases (leb (q2-\fst pol) 126) in ⊢ (???% → %);
854        |2,4,6,8,10,12,14,16,18,20: lapply (refl ? (leb (\fst pol-q2) 129)) cases (leb (\fst pol-q2) 129) in ⊢ (???% → %);
855        ]
856        #Hle2 normalize nodelta #Hli @(ex_intro ?? id) >H
857        <(pair_eq1 ?????? (Some_eq ??? Hli)) @refl
858      ]
859    |4,5,10,11: #id normalize nodelta whd in match (select_jump_length ???);
860      whd in match (select_call_length ???); >p3
861      lapply (refl ? (lookup_def ?? labels id 〈0,\fst pol〉))
862      cases (lookup_def ?? labels id 〈0,\fst pol〉) in ⊢ (???% → %); #q1 #q2
863      normalize nodelta #H
864      [1,3: cases (leb (\fst pol) q2)
865        [1,3: cases (leb (q2-\fst pol) 126) |2,4: cases (leb (\fst pol-q2) 129) ]
866        [1,3,5,7: normalize nodelta #H2 >(pair_eq1 ?????? (Some_eq ??? H2)) in H;
867        #Hli @(ex_intro ?? id) lapply (proj2 ?? Hl)
868        #H >(pair_eq1 ?????? (pair_eq1 ?????? H))
869        >(pair_eq2 ?????? (pair_eq1 ?????? H)) >Hli @refl]
870      ]
871      cases (split ? 5 11 (bitvector_of_nat 16 q2)) #n1 #n2
872      cases (split ? 5 11 (bitvector_of_nat 16 (\fst pol))) #m1 #m2
873      normalize nodelta cases (eq_bv ? n1 m1)
874      normalize nodelta #H2 >(pair_eq1 ?????? (Some_eq ??? H2)) in H; #H
875      @(ex_intro ?? id) lapply (proj2 ?? Hl) #H2
876      >(pair_eq1 ?????? (pair_eq1 ?????? H2)) >(pair_eq2 ?????? (pair_eq1 ?????? H2))
877      >H @refl
878    ]
879  ]
880 ]
881|2,4: (* jump_in_policy *)
882  #i #Hi cases (le_to_or_lt_eq … Hi) -Hi;
883  [1,3: >append_length <commutative_plus #Hi normalize in Hi;
884    >(nth_append_first ?? prefix ??(le_S_S_to_le ?? Hi)) @conj
885    [1,3: #Hj lapply (proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy)))) i (le_S_S_to_le … Hi))
886      #Hacc elim (proj1 ?? Hacc Hj) #h #n elim n -n #n #H elim H -H #j #Hj
887      @(ex_intro ?? h (ex_intro ?? n (ex_intro ?? j ?))) whd in match (snd ???);
888      >lookup_opt_insert_miss [1,3: @Hj |2,4:  @bitvector_of_nat_abs ]
889      [3,6: @(lt_to_not_eq i (|prefix|)) @(le_S_S_to_le … Hi)
890      |1,4: @(transitive_lt ??? (le_S_S_to_le ?? Hi))
891      ]
892      @(transitive_lt … (pi2 ?? program)) >prf >append_length normalize <plus_n_Sm
893      @le_S_S @le_plus_n_r
894    |2,4: lapply (proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy)))) i (le_S_S_to_le … Hi))
895      #Hacc #H elim H -H; #h #H elim H -H; #n #H elim H -H #j #Hl
896      @(proj2 ?? Hacc) @(ex_intro ?? h (ex_intro ?? n (ex_intro ?? j ?)))
897      <Hl @sym_eq @lookup_opt_insert_miss @bitvector_of_nat_abs
898      [3,6: @lt_to_not_eq @(le_S_S_to_le … Hi)
899      |1,4: @(transitive_lt ??? (le_S_S_to_le ?? Hi))
900      ]
901      @(transitive_lt … (pi2 ?? program)) >prf >append_length normalize <plus_n_Sm
902      @le_S_S @le_plus_n_r
903    ]
904  |2,4: >append_length <commutative_plus #Hi normalize in Hi; >(injective_S … Hi)
905    >(nth_append_second ?? prefix ?? (le_n (|prefix|)))
906     <minus_n_n whd in match (nth ????); normalize nodelta in p2; cases instr in p2;
907     [1,7: #pi | 2,3,8,9: #x | 4,5,10,11: #id | 6,12: #x #y] #Hinstr @conj normalize nodelta
908     [5,7,9,11,21,23: #H @⊥ @H (* instr is not a jump *)
909     |6,8,10,12,22,24: normalize nodelta in Hinstr; lapply (jmeq_to_eq ??? Hinstr)
910      #H destruct (H)
911     |13,15,17,19: (* instr is a jump *) #_ @(ex_intro ?? (\fst pol))
912       @(ex_intro ?? addr) @(ex_intro ?? (max_length old_length ai))
913       @lookup_opt_insert_hit
914     |14,16,18,20: #_ / by I/
915     |1,2,3,4: cases pi in Hinstr;
916       [35,36,37,109,110,111: #Hinstr #H @⊥ @H
917       |4,5,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,78,79,82,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106:
918         #x #Hinstr #H @⊥ @H
919       |1,2,3,6,7,33,34,75,76,77,80,81,107,108: #x #y #Hinstr #H @⊥ @H
920       |9,10,14,15,83,84,88,89: #id #Hinstr #_
921         @(ex_intro ?? (\fst pol)) @(ex_intro ?? addr) @(ex_intro ?? (max_length old_length ai))
922         @lookup_opt_insert_hit
923       |11,12,13,16,17,85,86,87,90,91: #x #id #Hinstr #_
924         @(ex_intro ?? (\fst pol)) @(ex_intro ?? addr) @(ex_intro ?? (max_length old_length ai))
925         @lookup_opt_insert_hit
926       |72,73,74,146,147,148: #Hinstr lapply (jmeq_to_eq ??? Hinstr) #H normalize in H; destruct (H)
927       |41,42,45,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,115,116,119,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143:
928        #x #Hinstr lapply (jmeq_to_eq ??? Hinstr) #H normalize in H; destruct (H)
929       |38,39,40,43,44,70,71,112,113,114,117,118,144,145: #x #y #Hinstr lapply (jmeq_to_eq ??? Hinstr) #H
930         normalize in H; destruct (H)
931       |46,47,51,52,120,121,125,126: #id #Hinstr #_ / by I/
932       |48,49,50,53,54,122,123,124,127,128: #x #id #Hinstr #_ / by I/
933       ]
934     ]
935   ]
936 ]
937|2,4: (* policy increase *)
938  #i >append_length >commutative_plus #Hi normalize in Hi;
939  cases (le_to_or_lt_eq … Hi) -Hi; #Hi
940  [1,3: >lookup_insert_miss
941    [1,3: @(proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy))) i (le_S_S_to_le … Hi))
942    |2,4: @bitvector_of_nat_abs
943      [3,6: @lt_to_not_eq @(le_S_S_to_le … Hi)
944      |1,4: @(transitive_lt ??? (le_S_S_to_le … Hi))
945      ]
946      @(transitive_lt … (pi2 ?? program)) >prf >append_length normalize <plus_n_Sm
947      @le_S_S @le_plus_n_r
948    ]
949  |2: >(injective_S … Hi) normalize nodelta in Hlength; >lookup_insert_hit normalize nodelta
950    >Hlength @pair_elim #l1 #l2 #Hl @pair_elim #y1 #y2 #Hy
951    >Hl %2 @refl
952  |4: cases daemon (* XXX get rest of proof done first *)
953  ]
954 ]
955|2,4: (* policy_safe *)
956  @lookup_forall #x cases x -x #x cases x -x #p #a #j #n normalize nodelta #Hl
957  elim (insert_lookup_opt ?? 〈p,a,j〉 ???? Hl) -Hl #Hl
958  [1,3: @(forall_lookup … (proj2 ?? (proj1 ?? (proj1 ?? Hpolicy))) ? n Hl)
959  |2,4: normalize nodelta in p2; cases instr in p2;
960    [2,3,8,9: #x #abs normalize in abs; lapply (jmeq_to_eq ??? abs) #H destruct (H)
961    |6,12: #x #y #abs normalize in abs; lapply (jmeq_to_eq ??? abs) #H destruct (H)
962    |1,7: #pi cases pi normalize nodelta
963     [35,36,37,72,73,74: #abs normalize in abs; lapply (jmeq_to_eq ??? abs) #H destruct (H)
964     |4,5,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,41,42,45,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69:
965       #x #abs normalize in abs; lapply (jmeq_to_eq ??? abs) #H destruct (H)
966     |1,2,3,6,7,33,34,38,39,40,43,44,70,71:
967       #x #y #abs normalize in abs; lapply (jmeq_to_eq ??? abs) #H destruct (H)
968     |9,10,14,15,46,47,51,52: #id >p3 whd in match (jump_expansion_step_instruction ???);
969       whd in match (select_reljump_length ???);
970       cases (lookup_def ?? labels id 〈0,\fst pol〉) #q1 #q2 normalize nodelta
971       >(pair_eq1 ?????? (pair_eq1 ?????? (proj2 ?? Hl)))
972       >(pair_eq2 ?????? (pair_eq1 ?????? (proj2 ?? Hl))) lapply (refl ? (leb (\fst pol) q2))
973       cases (leb (\fst pol) q2) in ⊢ (???% → %); #Hle1
974       [1,3,5,7,9,11,13,15: lapply (refl ? (leb (q2-\fst pol) 126)) cases (leb (q2-\fst pol) 126) in ⊢ (???% → %);
975       |2,4,6,8,10,12,14,16: lapply (refl ? (leb (\fst pol-q2) 129)) cases (leb (\fst pol-q2) 129) in ⊢ (???% → %);
976       ]
977       #Hle2 normalize nodelta #Hli
978       <(pair_eq1 ?????? (Some_eq ??? Hli)) >Hle1
979       >(pair_eq2 ?????? (proj2 ?? Hl)) <(pair_eq2 ?????? (Some_eq ??? Hli))
980       cases (\snd (lookup ?? (bitvector_of_nat ? (|prefix|)) (\snd old_policy) ?))
981       [1,7,13,19,25,31,37,43,49,55,61,67,73,79,85,91: @(leb_true_to_le … Hle2)
982       ] normalize @I (* much faster than / by I/, strangely enough *)
983     |11,12,13,16,17,48,49,50,53,54: #x #id >p3 whd in match (jump_expansion_step_instruction ???);
984       whd in match (select_reljump_length ???);
985       cases (lookup_def ?? labels id 〈0,\fst pol〉) #q1 #q2 normalize nodelta
986       >(pair_eq1 ?????? (pair_eq1 ?????? (proj2 ?? Hl)))
987       >(pair_eq2 ?????? (pair_eq1 ?????? (proj2 ?? Hl))) lapply (refl ? (leb (\fst pol) q2))
988       cases (leb (\fst pol) q2) in ⊢ (???% → %); #Hle1
989       [1,3,5,7,9,11,13,15,17,19: lapply (refl ? (leb (q2-\fst pol) 126)) cases (leb (q2-\fst pol) 126) in ⊢ (???% → %);
990       |2,4,6,8,10,12,14,16,18,20: lapply (refl ? (leb (\fst pol-q2) 129)) cases (leb (\fst pol-q2) 129) in ⊢ (???% → %);
991       ]
992       #Hle2 normalize nodelta #Hli
993       <(pair_eq1 ?????? (Some_eq ??? Hli)) >Hle1 >(pair_eq2 ?????? (proj2 ?? Hl))
994       <(pair_eq2 ?????? (Some_eq ??? Hli))
995       cases (\snd (lookup ?? (bitvector_of_nat ? (|prefix|)) (\snd old_policy) ?))
996       [1,7,13,19,25,31,37,43,49,55,61,67,73,79,85,91,97,103,109,115: @(leb_true_to_le … Hle2)
997       ] normalize @I (* vide supra *)
998     ]
999    |4,5,10,11: #id >p3 normalize nodelta whd in match (select_jump_length ???);
1000      whd in match (select_call_length ???); cases (lookup_def ?? labels id 〈0,\fst pol〉)
1001      #q1 #q2 normalize nodelta
1002      >(pair_eq1 ?????? (pair_eq1 ?????? (proj2 ?? Hl)))
1003      >(pair_eq2 ?????? (pair_eq1 ?????? (proj2 ?? Hl)))
1004      [1,3: lapply (refl ? (leb (\fst pol) q2)) cases (leb (\fst pol) q2) in ⊢ (???% → %); #Hle1
1005        [1,3: lapply (refl ? (leb (q2-\fst pol) 126)) cases (leb (q2-\fst pol) 126) in ⊢ (???% → %);
1006        |2,4: lapply (refl ? (leb (\fst pol-q2) 129)) cases (leb (\fst pol-q2) 129) in ⊢ (???% → %);
1007        ]
1008       #Hle2 normalize nodelta
1009      ]
1010      [2,4,6,8,9,10: lapply (refl ? (split ? 5 11 (bitvector_of_nat ? q2)))
1011        cases (split ??? (bitvector_of_nat ? q2)) in ⊢ (???% → %); #x1 #x2 #Hle3
1012        lapply (refl ? (split ? 5 11 (bitvector_of_nat ? (\fst pol))))
1013        cases (split ??? (bitvector_of_nat ? (\fst pol))) in ⊢ (???% → %); #y1 #y2 #Hle4
1014        normalize nodelta lapply (refl ? (eq_bv 5 x1 y1))
1015        cases (eq_bv 5 x1 y1) in ⊢ (???% → %); #Hle5
1016      ]
1017      #Hli <(pair_eq1 ?????? (Some_eq ??? Hli)) >(pair_eq2 ?????? (proj2 ?? Hl))
1018      <(pair_eq2 ?????? (Some_eq ??? Hli))
1019      cases (\snd (lookup ?? (bitvector_of_nat ? (|prefix|)) (\snd old_policy) ?))
1020      [2,8,14,20,26,32: >Hle3 @Hle5
1021      |37,40,43,46: >Hle1 @(leb_true_to_le … Hle2)
1022      ] normalize @I (* here too *)
1023    ]
1024  ]
1025 ]
1026|2,4: (* changed *)
1027  normalize nodelta #Hc [2: destruct (Hc)] #i #Hi cases (le_to_or_lt_eq … Hi) -Hi
1028  >append_length >commutative_plus #Hi
1029  normalize in Hi;
1030  [ >lookup_insert_miss
1031    [ @(proj2 ?? (proj1 ?? Hpolicy) Hc i (le_S_S_to_le … Hi))
1032    | @bitvector_of_nat_abs
1033      [3: @lt_to_not_eq @(le_S_S_to_le … Hi)
1034      |1: @(transitive_lt ??? (le_S_S_to_le … Hi))
1035      ]
1036      @(transitive_lt … (pi2 ?? program)) >prf >append_length normalize <plus_n_Sm
1037      @le_S_S @le_plus_n_r
1038    ]
1039  | >(injective_S … Hi) >lookup_insert_hit normalize nodelta in Hlength; >Hlength
1040    normalize nodelta @pair_elim #l1 #l2 #Hl @pair_elim #y1 #y2 #Hy >Hl @refl
1041  ]
1042 ]
1043|2,4: (* policy_isize_sum XXX *) cases daemon
1044]
1045| (* Case where add_instr = None *) normalize nodelta lapply (pi2 ?? acc) >p >p1
1046  normalize nodelta #Hpolicy
1047  @conj [ @conj [ @conj [ @conj [ @conj [ @conj
1048[ (* out_of_program_none *) #i >append_length >commutative_plus #Hi normalize in Hi;
1049  #Hi2 @(proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy))))) i (le_S_to_le ?? Hi) Hi2)
1050| (* labels_okay *) @lookup_forall #x cases x -x #x cases x #p #a #j #lbl #Hl normalize nodelta
1051  elim (forall_lookup … (proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy)))))) ? lbl Hl)
1052  #id #Hid @(ex_intro … id Hid)
1053 ]
1054| (* jump_in_policy *) #i >append_length >commutative_plus #Hi normalize in Hi;
1055  elim (le_to_or_lt_eq … Hi) -Hi #Hi
1056  [ >(nth_append_first ?? prefix ?? (le_S_S_to_le ?? Hi))
1057    @(proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy)))) i (le_S_S_to_le ?? Hi))
1058  | >(injective_S … Hi) @conj
1059    [ >(nth_append_second ?? prefix ?? (le_n (|prefix|))) <minus_n_n whd in match (nth ????);
1060      normalize nodelta in p2; cases instr in p2;
1061      [ #pi cases pi
1062        [1,2,3,6,7,33,34: #x #y #_ #H @⊥ @H
1063        |4,5,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32: #x #_ #H @⊥ @H
1064        |9,10,14,15: #id (* normalize segfaults here *) normalize nodelta
1065          whd in match (jump_expansion_step_instruction ???);
1066          #H lapply (jmeq_to_eq ??? H) #H2 destruct (H2)
1067        |11,12,13,16,17: #x #id normalize nodelta
1068          whd in match (jump_expansion_step_instruction ???);
1069          #H lapply (jmeq_to_eq ??? H) #H2 destruct (H2)
1070        |35,36,37: #_ #H @⊥ @H
1071        ]
1072      |2,3: #x #_ #H @⊥ @H
1073      |4,5: #id normalize nodelta #H lapply (jmeq_to_eq ??? H) #H2 destruct (H2)
1074      |6: #x #id #_ #H @⊥ @H
1075      ]
1076    | #H elim H -H #p #H elim H -H #a #H elim H -H #j #H
1077      >(proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy))))) (|prefix|) (le_n (|prefix|)) ?) in H;
1078      [ #H destruct (H)
1079      | @(transitive_lt … (pi2 ?? program)) >prf >append_length normalize <plus_n_Sm
1080        @le_S_S @le_plus_n_r
1081      ]
1082    ]
1083  ]
1084 ]
1085| (* policy_increase *) #i >append_length >commutative_plus #Hi normalize in Hi;
1086  elim (le_to_or_lt_eq … Hi) -Hi #Hi
1087  [ @(proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy))) i (le_S_S_to_le … Hi))
1088  | >(injective_S … Hi) >lookup_opt_lookup_miss
1089    [ >lookup_opt_lookup_miss
1090      [ normalize nodelta %2 @refl
1091      | @(proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy))))) (|prefix|) (le_n (|prefix|)) ?)
1092        @(transitive_lt … (pi2 ?? program)) >prf >append_length normalize <plus_n_Sm
1093        @le_S_S @le_plus_n_r
1094      ]
1095    | @(proj1 ?? (jump_not_in_policy (pi1 … program) «pi1 ?? old_policy,proj1 ?? (proj1 ?? (pi2 ?? old_policy))» (|prefix|) ?)) >prf
1096      [ >append_length normalize <plus_n_Sm @le_S_S @le_plus_n_r
1097      | >(nth_append_second ?? prefix ?? (le_n (|prefix|))) <minus_n_n >p1
1098        whd in match (nth ????); normalize nodelta in p2; cases instr in p2;
1099        [ #pi cases pi
1100          [1,2,3,6,7,33,34: #x #y #_ normalize /2 by nmk/
1101          |4,5,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32: #x #_ normalize /2 by nmk/
1102          |9,10,14,15: #id (* normalize segfaults here *) normalize nodelta
1103            whd in match (jump_expansion_step_instruction ???);
1104            #H lapply (jmeq_to_eq ??? H) #H2 destruct (H2)
1105          |11,12,13,16,17: #x #id normalize nodelta
1106            whd in match (jump_expansion_step_instruction ???);
1107            #H lapply (jmeq_to_eq ??? H) #H2 destruct (H2)
1108          |35,36,37: #_ normalize /2 by nmk/
1109          ]
1110        |2,3: #x #_ normalize /2 by nmk/
1111        |4,5: #id normalize nodelta #H lapply (jmeq_to_eq ??? H) #H2 destruct (H2)
1112        |6: #x #id #_ normalize /2 by nmk/
1113        ]
1114      ]
1115    ]
1116  ]
1117 ]
1118| (* policy_safe *) @lookup_forall #x cases x -x #x cases x -x #p #a #j #n #Hl
1119  @(forall_lookup … (proj2 ?? (proj1 ?? (proj1 ?? Hpolicy))) ? n Hl)
1120 ]
1121| (* changed *) #Hc #i >append_length >commutative_plus #Hi normalize in Hi;
1122  elim (le_to_or_lt_eq … Hi) -Hi #Hi
1123  [ @(proj2 ?? (proj1 ?? Hpolicy) Hc i (le_S_S_to_le … Hi))
1124  | >(injective_S … Hi) >lookup_opt_lookup_miss
1125    [ >lookup_opt_lookup_miss
1126      [ normalize nodelta @refl
1127      | @(proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpolicy))))) (|prefix|) (le_n (|prefix|)) ?)
1128        @(transitive_lt … (pi2 ?? program)) >prf >append_length normalize <plus_n_Sm
1129        @le_S_S @le_plus_n_r
1130      ]
1131    | @(proj1 ?? (jump_not_in_policy (pi1 … program) «pi1 ?? old_policy,proj1 ?? (proj1 ?? (pi2 ?? old_policy))» (|prefix|) ?)) >prf
1132      [ >append_length normalize <plus_n_Sm @le_S_S @le_plus_n_r
1133      | >(nth_append_second ?? prefix ?? (le_n (|prefix|))) <minus_n_n >p1
1134        whd in match (nth ????); normalize nodelta in p2; cases instr in p2;
1135        [ #pi cases pi
1136          [1,2,3,6,7,33,34: #x #y #_ normalize /2 by nmk/
1137          |4,5,8,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32: #x #_ normalize /2 by nmk/
1138          |9,10,14,15: #id (* normalize segfaults here *) normalize nodelta
1139            whd in match (jump_expansion_step_instruction ???);
1140            #H lapply (jmeq_to_eq ??? H) #H2 destruct (H2)
1141          |11,12,13,16,17: #x #id normalize nodelta
1142            whd in match (jump_expansion_step_instruction ???);
1143            #H lapply (jmeq_to_eq ??? H) #H2 destruct (H2)
1144          |35,36,37: #_ normalize /2 by nmk/
1145          ]
1146        |2,3: #x #_ normalize /2 by nmk/
1147        |4,5: #id normalize nodelta #H lapply (jmeq_to_eq ??? H) #H2 destruct (H2)
1148        |6: #x #id #_ normalize /2 by nmk/
1149        ]
1150      ]
1151    ]
1152  ]
1153 ]
1154| (* XXX policy_isize_sum *) cases daemon
1155]
1156| @conj [ @conj [ @conj [ @conj [ @conj [ @conj
1157  [ #i #Hi / by refl/
1158  | / by I/
1159  ]
1160  | #i #Hi @conj [ >nth_nil #H @⊥ @H | #H elim H #x #H1 elim H1 #y #H2 elim H2 #z #H3
1161                   normalize in H3; destruct (H3) ]
1162  ]                 
1163  | #i #Hi @⊥ @(absurd (i<0)) [ @Hi | @(not_le_Sn_O) ]
1164  ]
1165  | / by I/
1166  ]
1167  | #_ #i #Hi @⊥ @(absurd (i < 0)) [ @Hi | @not_le_Sn_O ]
1168  ]
1169  | / by refl/
1170  ]
1171]
1172qed.
1173
1174(* this might be replaced by a coercion: (∀x.A x → B x) → Σx.A x → Σx.B x *)
1175(* definition weaken_policy:
1176  ∀program,op.
1177  option (Σp:jump_expansion_policy.
1178    And (And (And (And (out_of_program_none program p)
1179    (labels_okay (create_label_map program op) p))
1180    (jump_in_policy program p)) (policy_increase program op p))
1181    (policy_safe p)) →
1182  option (Σp:jump_expansion_policy.And (out_of_program_none program p)
1183    (jump_in_policy program p)) ≝
1184 λprogram.λop.λx.
1185 match x return λ_.option (Σp.And (out_of_program_none program p) (jump_in_policy program p)) with
1186 [ None ⇒ None ?
1187 | Some z ⇒ Some ? (mk_Sig ?? (pi1 ?? z) ?)
1188 ].
1189@conj
1190[ @(proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (pi2 ?? z)))))
1191| @(proj2 ?? (proj1 ?? (proj1 ?? (pi2 ?? z))))
1192]
1193qed. *)
1194
1195(* This function executes n steps from the starting point. *)
1196(*let rec jump_expansion_internal (program: Σl:list labelled_instruction.lt (|l|) 2^16)
1197  (n: ℕ) on n:(Σx:bool × ℕ × (option jump_expansion_policy).
1198    let 〈ch,pc,y〉 ≝ x in
1199    match y with
1200    [ None ⇒ pc > 2^16
1201    | Some p ⇒ And (out_of_program_none program p) (jump_in_policy program p)
1202    ]) ≝
1203  match n with
1204  [ O   ⇒ 〈0,Some ? (pi1 … (jump_expansion_start program))〉
1205  | S m ⇒ let 〈ch,pc,z〉 as p1 ≝ (pi1 ?? (jump_expansion_internal program m)) in
1206          match z return λx. z=x → Σa:bool × ℕ × (option jump_expansion_policy).? with
1207          [ None    ⇒ λp2.〈pc,None ?〉
1208          | Some op ⇒ λp2.pi1 … (jump_expansion_step program (create_label_map program op) «op,?»)
1209          ] (refl … z)
1210  ].*)
1211
1212let rec jump_expansion_internal (program: Σl:list labelled_instruction.lt (|l|) 2^16) (n: ℕ)
1213  on n:(Σx:bool × (option jump_expansion_policy).
1214    let 〈c,pol〉 ≝ x in
1215    match pol with
1216    [ None ⇒ True
1217    | Some x ⇒ And (And (And (out_of_program_none program x) (jump_in_policy program x)) (\fst x < 2^16)) (policy_isize_sum program x)
1218    ]) ≝
1219  match n with
1220  [ O   ⇒ 〈true,Some ? (pi1 ?? (jump_expansion_start program))〉
1221  | S m ⇒ let 〈ch,z〉 as p1 ≝ (pi1 ?? (jump_expansion_internal program m)) in
1222          match z return λx. z=x → Σa:bool × (option jump_expansion_policy).? with
1223          [ None    ⇒ λp2.〈false,None ?〉
1224          | Some op ⇒ λp2.if ch
1225            then pi1 ?? (jump_expansion_step program (create_label_map program op) «op,?»)
1226            else (jump_expansion_internal program m)
1227          ] (refl … z)
1228  ].
1229[ normalize nodelta @conj
1230  [ @conj
1231    [ @(proj1 ?? (pi2 ?? (jump_expansion_start program)))
1232    | (* XXX *) cases daemon
1233    ]
1234  | (* XXX *) cases daemon
1235  ]
1236| lapply (pi2 ?? (jump_expansion_internal program m)) <p1 >p2 normalize nodelta / by /
1237| lapply (pi2 ?? (jump_expansion_internal program m)) <p1 >p2 normalize nodelta / by /
1238| normalize nodelta cases (jump_expansion_step program (create_label_map program op) «op,?»)
1239  #p cases p -p #p #r cases r normalize nodelta
1240  [ #H / by I/
1241  | #j #H @conj
1242    [ @conj
1243      [ @conj
1244        [ @(proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? H)))))))
1245        | @(proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? H))))))
1246        ]
1247      | @(proj2 ?? H)
1248      ]
1249    | @(proj2 ?? (proj1 ?? H))
1250    ]
1251  ]
1252]
1253qed.
1254
1255lemma pe_int_refl: ∀program.reflexive ? (policy_equal_int program).
1256#program whd #x whd #n #Hn
1257cases (bvt_lookup … (bitvector_of_nat 16 n) (\snd x) 〈0,0,short_jump〉)
1258#y cases y -y #y #z normalize nodelta @refl
1259qed.
1260
1261lemma pe_int_sym: ∀program.symmetric ? (policy_equal_int program).
1262#program whd #x #y #Hxy whd #n #Hn
1263lapply (Hxy n Hn) cases (bvt_lookup … (bitvector_of_nat ? n) (\snd x) 〈0,0,short_jump〉)
1264#z cases z -z #x1 #x2 #x3
1265cases (bvt_lookup … (bitvector_of_nat ? n) (\snd y) 〈0,0,short_jump〉)
1266#z cases z -z #y1 #y2 #y3 normalize nodelta //
1267qed.
1268 
1269lemma pe_int_trans: ∀program.transitive ? (policy_equal_int program).
1270#program whd #x #y #z whd in match (policy_equal_int ???); whd in match (policy_equal_int ?y ?);
1271whd in match (policy_equal_int ? x z); #Hxy #Hyz #n #Hn lapply (Hxy n Hn) -Hxy
1272lapply (Hyz n Hn) -Hyz cases (bvt_lookup … (bitvector_of_nat ? n) (\snd x) 〈0,0,short_jump〉)
1273#z cases z -z #x1 #x2 #x3
1274cases (bvt_lookup … (bitvector_of_nat ? n) (\snd y) 〈0,0,short_jump〉) #z cases z -z 
1275#y1 #y2 #y3
1276cases (bvt_lookup … (bitvector_of_nat ? n) (\snd z) 〈0,0,short_jump〉) #z cases z -z 
1277#z1 #z2 #z3 normalize nodelta //
1278qed.
1279
1280definition policy_equal ≝
1281  λprogram:list labelled_instruction.λp1,p2:option jump_expansion_policy.
1282  match p1 with
1283  [ Some x1 ⇒ match p2 with
1284              [ Some x2 ⇒ policy_equal_int program x1 x2
1285              | _       ⇒ False
1286              ]
1287  | None    ⇒ p2 = None ?
1288  ].
1289
1290lemma pe_refl: ∀program.reflexive ? (policy_equal program).
1291#program whd #x whd cases x
1292[ //
1293| #y @pe_int_refl
1294]
1295qed.
1296
1297lemma pe_sym: ∀program.symmetric ? (policy_equal program).
1298#program whd #x #y #Hxy whd cases y in Hxy;
1299[ cases x
1300  [ //
1301  | #x' #H @⊥ @(absurd ? H) /2 by nmk/
1302  ]
1303| #y' cases x
1304  [ #H @⊥ @(absurd ? H) whd in match (policy_equal ???); @nmk #H destruct (H)
1305  | #x' #H @pe_int_sym @H
1306  ]
1307]
1308qed.
1309
1310lemma pe_trans: ∀program.transitive ? (policy_equal program).
1311#program whd #x #y #z cases x
1312[ #Hxy #Hyz >Hxy in Hyz; //
1313| #x' cases y
1314  [ #H @⊥ @(absurd ? H) /2 by nmk/
1315  | #y' cases z
1316    [ #_ #H @⊥ @(absurd ? H) /2 by nmk/
1317    | #z' @pe_int_trans
1318    ]
1319  ]
1320]
1321qed.
1322
1323definition step_none: ∀program.∀n.
1324  (\snd (pi1 ?? (jump_expansion_internal program n))) = None ? →
1325  ∀k.(\snd (pi1 ?? (jump_expansion_internal program (n+k)))) = None ?.
1326#program #n lapply (refl ? (jump_expansion_internal program n))
1327 cases (jump_expansion_internal program n) in ⊢ (???% → %);
1328 #x1 cases x1 #p1 #j1 -x1; #H1 #Heqj #Hj #k elim k
1329[ <plus_n_O >Heqj @Hj
1330| #k' -k <plus_n_Sm whd in match (jump_expansion_internal program (S (n+k')));
1331  lapply (refl ? (jump_expansion_internal program (n+k')))
1332  cases (jump_expansion_internal program (n+k')) in ⊢ (???% → % → %);
1333  #x2 cases x2 -x2 #c2 #p2 normalize nodelta #H #Heqj2
1334  cases p2 in H Heqj2;
1335  [ #H #Heqj2 #_ whd in match (jump_expansion_internal ??);
1336    >Heqj2 normalize nodelta @refl
1337  | #x #H #Heqj2 #abs destruct (abs)
1338  ]
1339]
1340qed.
1341
1342lemma pe_step: ∀program:(Σl:list labelled_instruction.|l| < 2^16).
1343  ∀n.policy_equal program (\snd (pi1 ?? (jump_expansion_internal program n)))
1344   (\snd (pi1 ?? (jump_expansion_internal program (S n)))) →
1345  policy_equal program (\snd (pi1 ?? (jump_expansion_internal program (S n))))
1346    (\snd (pi1 ?? (jump_expansion_internal program (S (S n))))).
1347#program #n #Heq
1348cases daemon (* XXX *)
1349qed.
1350
1351(* this is in the stdlib, but commented out, why? *)
1352theorem plus_Sn_m1: ∀n,m:nat. S m + n = m + S n.
1353  #n (elim n) normalize /2 by S_pred/ qed.
1354 
1355lemma equal_remains_equal: ∀program:(Σl:list labelled_instruction.|l| < 2^16).∀n:ℕ.
1356  policy_equal program (\snd (pi1 … (jump_expansion_internal program n)))
1357   (\snd (pi1 … (jump_expansion_internal program (S n)))) →
1358  ∀k.k ≥ n → policy_equal program (\snd (pi1 … (jump_expansion_internal program n)))
1359   (\snd (pi1 … (jump_expansion_internal program k))).
1360#program #n #Heq #k #Hk elim (le_plus_k … Hk); #z #H >H -H -Hk -k;
1361lapply Heq -Heq; lapply n -n; elim z -z;
1362[ #n #Heq <plus_n_O @pe_refl
1363| #z #Hind #n #Heq <plus_Sn_m1 whd in match (plus (S n) z);
1364  @(pe_trans … (\snd (pi1 … (jump_expansion_internal program (S n)))))
1365  [ @Heq
1366  | @Hind @pe_step @Heq
1367  ]
1368]
1369qed.
1370
1371(* this number monotonically increases over iterations, maximum 2*|program| *)
1372let rec measure_int (program: list labelled_instruction) (policy: jump_expansion_policy) (acc: ℕ)
1373 on program: ℕ ≝
1374 match program with
1375 [ nil      ⇒ acc
1376 | cons h t ⇒ match (\snd (bvt_lookup ?? (bitvector_of_nat ? (|t|)) (\snd policy) 〈0,00
1377,short_jump〉)) with
1378   [ long_jump   ⇒ measure_int t policy (acc + 2)
1379   | medium_jump ⇒ measure_int t policy (acc + 1)
1380   | _           ⇒ measure_int t policy acc
1381   ]
1382 ].
1383
1384lemma measure_plus: ∀program.∀policy.∀x,d:ℕ.
1385 measure_int program policy (x+d) = measure_int program policy x + d.
1386#program #policy #x #d generalize in match x; -x elim d
1387[ //
1388| -d; #d #Hind elim program
1389  [ / by refl/
1390  | #h #t #Hd #x whd in match (measure_int ???); whd in match (measure_int ?? x);
1391    cases (\snd (lookup … (bitvector_of_nat ? (|t|)) (\snd policy) 〈0,0,short_jump〉))
1392    [ normalize nodelta @Hd
1393    |2,3: normalize nodelta >associative_plus >(commutative_plus (S d) ?) <associative_plus
1394      @Hd
1395    ]
1396  ]
1397]
1398qed.
1399
1400lemma measure_le: ∀program.∀policy.
1401  measure_int program policy 0 ≤ 2*|program|.
1402#program #policy elim program
1403[ normalize @le_n
1404| #h #t #Hind whd in match (measure_int ???);
1405  cases (\snd (lookup ?? (bitvector_of_nat ? (|t|)) (\snd policy) 〈0,0,short_jump〉))
1406  [ normalize nodelta @(transitive_le ??? Hind) /2 by monotonic_le_times_r/
1407  |2,3: normalize nodelta >measure_plus <times_n_Sm >(commutative_plus 2 ?)
1408    @le_plus [1,3: @Hind |2,4: / by le_n/ ]
1409  ]
1410]
1411qed.
1412
1413lemma measure_incr_or_equal: ∀program:Σl:list labelled_instruction.|l|<2^16.
1414  ∀policy:Σp:jump_expansion_policy.
1415    out_of_program_none program p ∧ jump_in_policy program p ∧ \fst p < 2^16 ∧ policy_isize_sum program p.
1416  ∀l.|l| ≤ |program| → ∀acc:ℕ.
1417  match \snd (jump_expansion_step program (create_label_map program policy) policy) with
1418  [ None   ⇒ True
1419  | Some p ⇒ measure_int l policy acc ≤ measure_int l p acc
1420  ].
1421#program #policy #l elim l -l;
1422[ #Hp #acc cases (jump_expansion_step ???) #pi1 cases pi1 #p #q -pi1; cases q [ // | #x #_ @le_n ]
1423| #h #t #Hind #Hp #acc
1424  lapply (refl ? (jump_expansion_step program (create_label_map program policy) policy))
1425  cases (jump_expansion_step ???) in ⊢ (???% → %); #pi1 cases pi1 -pi1 #c #r cases r
1426  [ / by I/
1427  | #x normalize nodelta #Hx #Hjeq lapply (proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hx)))) (|t|) Hp)
1428    whd in match (measure_int ???); whd in match (measure_int ? x ?);
1429    cases (bvt_lookup ?? (bitvector_of_nat ? (|t|)) (\snd policy) 〈0,0,short_jump〉)
1430    #z cases z -z #x1 #x2 #x3
1431    cases (bvt_lookup ?? (bitvector_of_nat ? (|t|)) (\snd x) 〈0,0,short_jump〉)
1432    #z cases z -z #y1 #y2 #y3
1433    normalize nodelta #Hj cases Hj
1434    [ cases x3 cases y3
1435      [1,4,5,7,8,9: #H @⊥ @H
1436      |2,3,6: #_ normalize nodelta
1437        [1,2: @(transitive_le ? (measure_int t x acc))
1438        |3: @(transitive_le ? (measure_int t x (acc+1)))
1439        ]
1440        [2,4,5,6: >measure_plus [1,2: @le_plus_n_r] >measure_plus @le_plus / by le_n/]
1441        >Hjeq in Hind; #Hind @Hind @(transitive_le … Hp) @le_n_Sn
1442        ]
1443    | #Heq >Heq cases y3 normalize nodelta
1444      [2,3: >measure_plus >measure_plus @le_plus / by le_n/]
1445      >Hjeq in Hind; #Hind @Hind @(transitive_le … Hp) @le_n_Sn
1446    ]
1447  ]
1448]
1449qed.
1450
1451(* these lemmas seem superfluous, but not sure how *)
1452lemma bla: ∀a,b:ℕ.a + a = b + b → a = b.
1453 #a elim a
1454 [ normalize #b //
1455 | -a #a #Hind #b cases b [ /2 by le_n_O_to_eq/ | -b #b normalize
1456   <plus_n_Sm <plus_n_Sm #H
1457   >(Hind b (injective_S ?? (injective_S ?? H))) // ]
1458 ]
1459qed.
1460
1461lemma sth_not_s: ∀x.x ≠ S x.
1462 #x cases x
1463 [ // | #y // ]
1464qed.
1465 
1466lemma measure_full: ∀program.∀policy.
1467  measure_int program policy 0 = 2*|program| → ∀i.i<|program| →
1468  (\snd (bvt_lookup ?? (bitvector_of_nat ? i) (\snd policy) 〈0,0,short_jump〉)) = long_jump.
1469#program #policy elim program
1470[ #Hm #i #Hi @⊥ @(absurd … Hi) @not_le_Sn_O
1471| #h #t #Hind #Hm #i #Hi cut (measure_int t policy 0 = 2*|t|)
1472  [ whd in match (measure_int ???) in Hm;
1473    cases (\snd (lookup … (bitvector_of_nat ? (|t|)) (\snd policy) 〈0,0,short_jump〉)) in Hm;
1474    normalize nodelta
1475    [ #H @⊥ @(absurd ? (measure_le t policy)) >H @lt_to_not_le /2 by lt_plus, le_n/
1476    | >measure_plus >commutative_plus #H @⊥ @(absurd ? (measure_le t policy))
1477      <(plus_to_minus … (sym_eq … H)) @lt_to_not_le normalize
1478      >(commutative_plus (|t|) 0) <plus_O_n <minus_n_O
1479      >plus_n_Sm @le_n
1480    | >measure_plus <times_n_Sm >commutative_plus #H lapply (injective_plus_r … H) //
1481    ]
1482  | #Hmt cases (le_to_or_lt_eq … Hi) -Hi;
1483  [ #Hi @(Hind Hmt i (le_S_S_to_le … Hi))
1484  | #Hi >(injective_S … Hi) whd in match (measure_int ???) in Hm;
1485    cases (\snd (lookup … (bitvector_of_nat ? (|t|)) (\snd policy) 〈0,0,short_jump〉)) in Hm;
1486    normalize nodelta
1487    [ >Hmt normalize <plus_n_O >(commutative_plus (|t|) (S (|t|)))
1488      >plus_n_Sm #H @⊥ @(absurd ? (bla ?? H)) @sth_not_s
1489    | >measure_plus >Hmt normalize <plus_n_O >commutative_plus normalize
1490      #H @⊥ @(absurd ? (injective_plus_r … (injective_S ?? H))) @sth_not_s
1491    | #_ //
1492    ]
1493  ]]
1494]
1495qed.
1496
1497lemma measure_special: ∀program:(Σl:list labelled_instruction.|l| < 2^16).
1498  ∀policy:Σp:jump_expansion_policy.
1499    out_of_program_none program p ∧ jump_in_policy program p ∧ \fst p < 2^16 ∧ policy_isize_sum program p.
1500  match (\snd (pi1 ?? (jump_expansion_step program (create_label_map program policy) policy))) with
1501  [ None ⇒ True
1502  | Some p ⇒ measure_int program policy 0 = measure_int program p 0 → policy_equal_int program policy p ].
1503#program #policy lapply (refl ? (pi1 ?? (jump_expansion_step program (create_label_map program policy) policy)))
1504cases (jump_expansion_step program (create_label_map program policy) policy) in ⊢ (???% → %);
1505#p cases p -p #ch #pol normalize nodelta cases pol
1506[ / by I/
1507| #p normalize nodelta #Hpol #eqpol lapply (le_n (|program|))
1508  @(list_ind ?  (λx.|x| ≤ |pi1 ?? program| →
1509      measure_int x policy 0 = measure_int x p 0 →
1510      policy_equal_int x policy p) ?? (pi1 ?? program))
1511 [ #_ #_ #i #Hi @⊥ @(absurd ? Hi) @not_le_Sn_O
1512 | #h #t #Hind #Hp #Hm #i #Hi cases (le_to_or_lt_eq … Hi) -Hi;
1513   [ #Hi @Hind
1514     [ @(transitive_le … Hp) / by /
1515     | whd in match (measure_int ???) in Hm; whd in match (measure_int ? p ?) in Hm;
1516       lapply (proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpol)))) (|t|) Hp)
1517       cases (bvt_lookup ?? (bitvector_of_nat ? (|t|)) ? 〈0,0,short_jump〉) in Hm;
1518       #x cases x -x #x1 #x2 #x3
1519       cases (bvt_lookup ?? (bitvector_of_nat ? (|t|)) ? 〈0,0,short_jump〉);
1520       #y cases y -y #y1 #y2 #y3
1521       cases x3 cases y3 normalize nodelta
1522       [1: #H #_ @H
1523       |2,3: >measure_plus #H #_ @⊥ @(absurd ? (eq_plus_S_to_lt … H)) @le_to_not_lt
1524         lapply (measure_incr_or_equal program policy t ? 0)
1525         [1,3: @(transitive_le … Hp) @le_n_Sn ] >eqpol / by /
1526       |4,7,8: #_ #H elim H #H2 [1,3,5: @⊥ @H2 |2,4,6: destruct (H2) ]
1527       |5: >measure_plus >measure_plus >commutative_plus >(commutative_plus ? 1)
1528         #H #_ @(injective_plus_r … H)
1529       |6: >measure_plus >measure_plus
1530          change with (1+1) in match (2); >assoc_plus1 >(commutative_plus 1 (measure_int ???))
1531          #H #_ @⊥ @(absurd ? (eq_plus_S_to_lt … H)) @le_to_not_lt @monotonic_le_plus_l
1532          lapply (measure_incr_or_equal program policy t ? 0)
1533          [ @(transitive_le … Hp) @le_n_Sn ] >eqpol / by /
1534       |9: >measure_plus >measure_plus >commutative_plus >(commutative_plus ? 2)
1535         #H #_ @(injective_plus_r … H)
1536       ]
1537     | @(le_S_S_to_le … Hi)
1538     ]
1539   | #Hi >(injective_S … Hi) whd in match (measure_int ???) in Hm;
1540     whd in match (measure_int ? p ?) in Hm;
1541     lapply (proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? Hpol)))) (|t|) Hp)
1542     cases (bvt_lookup ?? (bitvector_of_nat ? (|t|)) ? 〈0,0,short_jump〉) in   
1543Hm;
1544     #x cases x -x #x1 #x2 #x3
1545     cases (bvt_lookup ?? (bitvector_of_nat ? (|t|)) ? 〈0,0,short_jump〉);
1546     #y cases y -y #y1 #y2 #y3
1547     normalize nodelta cases x3 cases y3 normalize nodelta
1548     [1,5,9: #_ #_ //
1549     |4,7,8: #_ #H elim H #H2 [1,3,5: @⊥ @H2 |2,4,6: destruct (H2) ]
1550     |2,3: >measure_plus #H #_ @⊥ @(absurd ? (eq_plus_S_to_lt … H)) @le_to_not_lt
1551       lapply (measure_incr_or_equal program policy t ? 0)
1552       [1,3: @(transitive_le … Hp) @le_n_Sn ] >eqpol / by /
1553     |6: >measure_plus >measure_plus
1554        change with (1+1) in match (2); >assoc_plus1 >(commutative_plus 1 (measure_int ???))
1555        #H #_ @⊥ @(absurd ? (eq_plus_S_to_lt … H)) @le_to_not_lt @monotonic_le_plus_l
1556        lapply (measure_incr_or_equal program policy t ? 0)
1557        [ @(transitive_le … Hp) @le_n_Sn ] >eqpol / by /
1558     ]
1559   ]
1560 ]
1561qed.
1562
1563lemma le_to_eq_plus: ∀n,z.
1564  n ≤ z → ∃k.z = n + k.
1565 #n #z elim z
1566 [ #H cases (le_to_or_lt_eq … H)
1567   [ #H2 @⊥ @(absurd … H2) @not_le_Sn_O
1568   | #H2 @(ex_intro … 0) >H2 //
1569   ]
1570 | #z' #Hind #H cases (le_to_or_lt_eq … H)
1571   [ #H' elim (Hind (le_S_S_to_le … H')) #k' #H2 @(ex_intro … (S k'))
1572     >H2 >plus_n_Sm //
1573   | #H' @(ex_intro … 0) >H' //
1574   ]
1575 ]
1576qed.
1577
1578lemma measure_zero: ∀l.∀program:Σl:list labelled_instruction.|l| < 2^16.
1579  |l| ≤ |program| → measure_int l (jump_expansion_start program) 0 = 0.
1580 #l #program elim l
1581 [ //
1582 | #h #t #Hind #Hp whd in match (measure_int ???);
1583   cases (dec_is_jump (nth (|t|) ? program 〈None ?, Comment []〉)) #Hj
1584   [ >(lookup_opt_lookup_hit … (proj2 ?? (pi2 ?? (jump_expansion_start program)) (|t|) ? Hj) 〈0,0,short_jump〉)
1585     [ normalize nodelta @Hind @le_S_to_le ]
1586     @Hp
1587   | >(lookup_opt_lookup_miss … (proj1 ?? (jump_not_in_policy program (pi1 ?? (jump_expansion_start program)) (|t|) ?) Hj) 〈0,0,short_jump〉)
1588     [ normalize nodelta @Hind @le_S_to_le @Hp
1589     | @Hp
1590     | %
1591       [ @(proj1 ?? (proj1 ?? (pi2 ?? (jump_expansion_start program))))
1592       | @(proj2 ?? (proj1 ?? (pi2 ?? (jump_expansion_start program))))
1593       ]
1594     ]
1595   ]
1596 ]
1597qed.
1598
1599(* the actual computation of the fixpoint *)
1600definition je_fixpoint: ∀program:(Σl:list labelled_instruction.|l| < 2^16).
1601  Σp:option jump_expansion_policy.∃n.∀k.n < k →
1602    policy_equal program (\snd (pi1 ?? (jump_expansion_internal program k))) p.
1603#program @(\snd (pi1 ?? (jump_expansion_internal program (2*|program|))))
1604cases (dec_bounded_exists (λk.policy_equal (pi1 ?? program)
1605   (\snd (pi1 ?? (jump_expansion_internal program k)))
1606   (\snd (pi1 ?? (jump_expansion_internal program (S k))))) ? (2*|program|))
1607[ #Hex elim Hex -Hex #x #Hx @(ex_intro … x) #k #Hk
1608  @pe_trans
1609  [ @(\snd (pi1 ?? (jump_expansion_internal program x)))
1610  | @pe_sym @equal_remains_equal
1611    [ @(proj2 ?? Hx)
1612    | @le_S_S_to_le @le_S @Hk
1613    ]
1614  | @equal_remains_equal
1615    [ @(proj2 ?? Hx)
1616    | @le_S_S_to_le @le_S @(proj1 ?? Hx)
1617    ]   
1618  ]
1619| #Hnex lapply (not_exists_forall … Hnex) -Hnex; #Hfa @(ex_intro … (2*|program|)) #k #Hk
1620  @pe_sym @equal_remains_equal
1621  [ lapply (refl ? (jump_expansion_internal program (2*|program|)))
1622    cases (jump_expansion_internal program (2*|program|)) in ⊢ (???% → %);
1623    #x cases x -x #Fch #Fpol normalize nodelta #HFpol cases Fpol in HFpol; normalize nodelta
1624    [ (* if we're at None in 2*|program|, we're at None in S 2*|program| too *)
1625      #HFpol #EQ whd in match (jump_expansion_internal ??); >EQ
1626      normalize nodelta / by /
1627    | #Fp #HFp #EQ whd in match (jump_expansion_internal ??);
1628      >EQ normalize nodelta
1629      lapply (refl ? (jump_expansion_step program (create_label_map program Fp) «Fp,?»))
1630      [ @HFp
1631      | lapply (measure_full program Fp ?)
1632        [ @le_to_le_to_eq
1633          [ @measure_le
1634          | cut (∀x:ℕ.x ≤ 2*|program| →
1635             ∃p.(\snd (pi1 ?? (jump_expansion_internal program x)) = Some ? p ∧       
1636                x ≤ measure_int program p 0))
1637            [ #x elim x
1638              [ #Hx @(ex_intro ?? (jump_expansion_start program)) @conj
1639                [ whd in match (jump_expansion_internal ??); @refl
1640                | @le_O_n
1641                ]
1642              | -x #x #Hind #Hx
1643                lapply (refl ? (jump_expansion_internal program (S x)))
1644                cases (jump_expansion_internal program (S x)) in ⊢ (???% → %);
1645                #z cases z -z #Sxch #Sxpol cases Sxpol -Sxpol normalize nodelta
1646                [ #H #HeqSxpol @⊥ elim (le_to_eq_plus ?? Hx) #k #Hk
1647                  @(absurd … (step_none program (S x) ? k))
1648                  [ >HeqSxpol / by /
1649                  | <Hk >EQ @nmk #H destruct (H)
1650                  ]
1651                | #Sxpol #HSxpol #HeqSxpol @(ex_intro ?? Sxpol) @conj
1652                  [ @refl
1653                  | elim (Hind (transitive_le … (le_n_Sn x) Hx))
1654                    #xpol #Hxpol @(le_to_lt_to_lt … (proj2 ?? Hxpol))
1655                    lapply (measure_incr_or_equal program xpol program (le_n (|program|)) 0)
1656                    [ cases (jump_expansion_internal program x) in Hxpol;
1657                      #z cases z -z #xch #xpol normalize nodelta #H #H2 >(proj1 ?? H2) in H;
1658                      normalize nodelta / by /
1659                    | lapply (Hfa x Hx) lapply HeqSxpol -HeqSxpol
1660                      whd in match (jump_expansion_internal program (S x));
1661                      lapply (refl ? (jump_expansion_internal program x))
1662                      lapply Hxpol -Hxpol cases (jump_expansion_internal program x) in ⊢ (% → ???% → %);
1663                      #z cases z -z #xch #b normalize nodelta #H #Heq >(proj1 ?? Heq) in H;
1664                      #H #Heq cases xch in Heq; #Heq normalize nodelta
1665                      [ lapply (refl ? (jump_expansion_step program (create_label_map (pi1 ?? program) xpol) «xpol,H»))
1666                        cases (jump_expansion_step ???) in ⊢ (???% → %); #z cases z -z #a #c
1667                        normalize nodelta cases c normalize nodelta
1668                        [ #H1 #Heq #H2 destruct (H2)
1669                        | #d #H1 #Heq #H2 destruct (H2) #Hfull #H2 elim (le_to_or_lt_eq … H2)
1670                          [ / by /
1671                          | #H3 lapply (measure_special program «xpol,H») >Heq
1672                            normalize nodelta #H4 @⊥
1673                            @(absurd … (H4 H3))
1674                            @Hfull
1675                          ]
1676                        ]
1677                      | lapply (refl ? (jump_expansion_step program (create_label_map (pi1 ?? program) xpol) «xpol,H»))
1678                        cases (jump_expansion_step ???) in ⊢ (???% → %); #z cases z -z #a #c
1679                        normalize nodelta cases c normalize nodelta
1680                        [ #H1 #Heq #H2 #H3 #_ @⊥ @(absurd ?? H3) @pe_refl
1681                        | #d #H1 #Heq #H2 #H3 @⊥ @(absurd ?? H3) @pe_refl
1682                        ]
1683                      ]
1684                    ]
1685                  ]
1686                ]
1687              ]
1688            | #H elim (H (2*|program|) (le_n ?)) #plp >EQ #Hplp
1689              >(Some_eq ??? (proj1 ?? Hplp)) @(proj2 ?? Hplp)
1690            ]
1691          ]
1692        | #Hfull cases (jump_expansion_step program (create_label_map program Fp) «Fp,?») in ⊢ (???% → %);
1693          #x cases x -x #Gch #Gpol cases Gpol normalize nodelta
1694          [ #H #EQ2 @⊥ @(absurd ?? H) @Hfull
1695          | #Gp #HGp #EQ2 cases Fch
1696            [ normalize nodelta #i #Hi
1697              lapply (refl ? (lookup ?? (bitvector_of_nat 16 i) (\snd Fp) 〈0,0,short_jump〉))
1698              cases (lookup ?? (bitvector_of_nat 16 i) (\snd Fp) 〈0,0,short_jump〉) in ⊢ (???% → %);
1699              #x cases x -x #p #a #j normalize nodelta #H
1700              lapply (proj2 ?? (proj1 ?? (proj1 ?? (proj1 ?? (proj1 ?? HGp)))) i Hi) lapply (Hfull i Hi) >H
1701              #H2 >H2 normalize nodelta cases (lookup ?? (bitvector_of_nat 16 i) (\snd Gp) 〈0,0,short_jump〉)
1702              #x cases x -x #p #a #j' cases j' normalize nodelta #H elim H -H #H
1703              [1,3: @⊥ @H
1704              |2,4: destruct (H)
1705              |5,6: @refl
1706              ]
1707            | normalize nodelta /2 by pe_int_refl/
1708            ]
1709          ]
1710        ]
1711      ]
1712    ]
1713  | @le_S_S_to_le @le_S @Hk
1714  ]
1715| #n cases (jump_expansion_internal program n) cases (jump_expansion_internal program (S n))
1716  #x cases x -x #nch #npol normalize nodelta #Hnpol
1717  #x cases x -x #Sch #Spol normalize nodelta #HSpol
1718  cases npol in Hnpol; cases Spol in HSpol;
1719  [ #Hnpol #HSpol %1 //
1720  |2,3: #x #Hnpol #HSpol %2 @nmk whd in match (policy_equal ???); //
1721    #H destruct (H)
1722  |4: #np #Hnp #Sp #HSp whd in match (policy_equal ???); @dec_bounded_forall #m
1723      cases (bvt_lookup ?? (bitvector_of_nat 16 m) ? 〈0,0,short_jump〉)
1724      #x cases x -x #x1 #x2 #x3
1725      cases (bvt_lookup ?? (bitvector_of_nat ? m) ? 〈0,0,short_jump〉)
1726      #y cases y -y #y1 #y2 #y3 normalize nodelta
1727      @dec_eq_jump_length 
1728  ]
1729]
1730qed.
1731
1732(* Take a policy of 〈pc, addr, jump_length〉 tuples, and transform it into
1733 * a map from pc to jump_length. This cannot be done earlier because the pc
1734 * changes between iterations. *)
1735let rec transform_policy (n: nat) (policy: jump_expansion_policy) (acc: BitVectorTrie jump_length 16) on n:
1736  BitVectorTrie jump_length 16 ≝
1737  match n with
1738  [ O    ⇒ acc
1739  | S n' ⇒
1740    match lookup_opt … (bitvector_of_nat 16 n') (\snd policy) with
1741    [ None   ⇒ transform_policy n' policy acc
1742    | Some x ⇒ let 〈pc,addr,length〉 ≝ x in
1743      transform_policy n' policy (insert … (bitvector_of_nat 16 pc) length acc)
1744    ]
1745  ].
1746
1747(* The glue between Policy and Assembly. *)
1748definition jump_expansion':
1749 ∀program:preamble × (Σl:list labelled_instruction.|l| < 2^16).
1750 ∀lookup_labels.policy_type lookup_labels ≝
1751 λprogram.λlookup_labels.λpc.
1752  let policy ≝
1753    transform_policy (|\snd program|) (pi1 … (je_fixpoint (\snd program))) (Stub ??) in
1754  «bvt_lookup ? ? pc policy long_jump,?».
1755  cases daemon (* XXX later *)
1756qed.
Note: See TracBrowser for help on using the repository browser.