source: src/ASM/CostsProof.ma @ 1570

Last change on this file since 1570 was 1570, checked in by sacerdot, 8 years ago

Dependent type crazyness.

File size: 35.2 KB
Line 
1include "ASM/ASMCosts.ma".
2include "ASM/WellLabeled.ma".
3include "ASM/Status.ma".
4include "common/StructuredTraces.ma".
5
6(*
7definition next_instruction_is_labelled ≝
8  λcost_labels: BitVectorTrie Byte 16.
9  λs: Status.
10  let pc ≝ program_counter … (execute_1 s) in
11    match lookup_opt … pc cost_labels with
12    [ None ⇒ False
13    | _    ⇒ True
14    ].
15
16definition current_instruction_cost ≝
17  λs: Status. \snd (fetch (code_memory … s) (program_counter … s)).
18
19definition is_call_p ≝
20  λs.
21  match s with
22  [ ACALL _ ⇒ True
23  | LCALL _ ⇒ True
24  | JMP ⇒ True (* XXX: is function pointer call *)
25  | _ ⇒ False
26  ].
27
28definition next_instruction ≝
29  λs: Status.
30  let 〈instruction, ignore, ignore〉 ≝ fetch (code_memory … s) (program_counter … s) in
31    instruction.
32
33inductive trace_ends_with_ret: Type[0] ≝
34  | ends_with_ret: trace_ends_with_ret
35  | doesnt_end_with_ret: trace_ends_with_ret.
36
37definition next_instruction_is_labelled ≝
38  λcost_labels: BitVectorTrie Byte 16.
39  λs: Status.
40  let pc ≝ program_counter … (execute 1 s) in
41    match lookup_opt … pc cost_labels with
42    [ None ⇒ False
43    | _    ⇒ True
44    ].
45
46definition next_instruction_properly_relates_program_counters ≝
47  λbefore: Status.
48  λafter : Status.
49  let size ≝ current_instruction_cost before in
50  let pc_before ≝ program_counter … before in
51  let pc_after ≝ program_counter … after in
52  let sum ≝ \snd (half_add … pc_before (bitvector_of_nat … size)) in
53    sum = pc_after.
54
55definition current_instruction ≝
56  λs: Status.
57  let pc ≝ program_counter … s in
58  \fst (\fst (fetch … (code_memory … s) pc)).
59
60definition current_instruction_is_labelled ≝
61  λcost_labels: BitVectorTrie Byte 16.
62  λs: Status.
63  let pc ≝ program_counter … s in
64    match lookup_opt … pc cost_labels with
65    [ None ⇒ False
66    | _    ⇒ True
67    ].
68
69inductive trace_label_return (cost_labels: BitVectorTrie Byte 16): Status → Status → Type[0] ≝
70  | tlr_base:
71      ∀status_before: Status.
72      ∀status_after: Status.
73        trace_label_label cost_labels ends_with_ret status_before status_after →
74        trace_label_return cost_labels status_before status_after
75  | tlr_step:
76      ∀status_initial: Status.
77      ∀status_labelled: Status.
78      ∀status_final: Status.
79          trace_label_label cost_labels doesnt_end_with_ret status_initial status_labelled →
80            trace_label_return cost_labels status_labelled status_final →
81              trace_label_return cost_labels status_initial status_final
82with trace_label_label: trace_ends_with_ret → Status → Status → Type[0] ≝
83  | tll_base:
84      ∀ends_flag: trace_ends_with_ret.
85      ∀start_status: Status.
86      ∀end_status: Status.
87        trace_label_label_pre cost_labels ends_flag start_status end_status →
88        current_instruction_is_labelled cost_labels start_status →
89        trace_label_label cost_labels ends_flag start_status end_status
90with trace_label_label_pre: trace_ends_with_ret → Status → Status → Type[0] ≝
91  | tllp_base_not_return:
92      ∀start_status: Status.
93        let final_status ≝ execute 1 start_status in
94        current_instruction start_status ≠ (RealInstruction … (RET [[relative]])) →
95        ¬ (is_jump_p (current_instruction start_status)) →
96        current_instruction_is_labelled cost_labels final_status →
97          trace_label_label_pre cost_labels doesnt_end_with_ret start_status final_status
98  | tllp_base_return:
99      ∀start_status: Status.
100        let final_status ≝ execute 1 start_status in
101          current_instruction start_status = (RealInstruction … (RET [[relative]])) →
102            trace_label_label_pre cost_labels ends_with_ret start_status final_status
103  | tllp_base_jump:
104      ∀start_status: Status.
105        let final_status ≝ execute 1 start_status in
106          is_jump_p (current_instruction start_status) →
107            current_instruction_is_labelled cost_labels final_status →
108              trace_label_label_pre cost_labels doesnt_end_with_ret start_status final_status
109  | tllp_step_call:
110      ∀end_flag: trace_ends_with_ret.
111      ∀status_pre_fun_call: Status.
112      ∀status_after_fun_call: Status.
113      ∀status_final: Status.
114        let status_start_fun_call ≝ execute 1 status_pre_fun_call in
115          is_call_p (current_instruction status_pre_fun_call) →
116          next_instruction_properly_relates_program_counters status_pre_fun_call status_after_fun_call →
117          trace_label_return cost_labels status_start_fun_call status_after_fun_call →
118          trace_label_label_pre cost_labels end_flag status_after_fun_call status_final →
119            trace_label_label_pre cost_labels end_flag status_pre_fun_call status_final
120  | tllp_step_default:
121      ∀end_flag: trace_ends_with_ret.
122      ∀status_pre: Status.
123      ∀status_end: Status.
124        let status_init ≝ execute 1 status_pre in
125          trace_label_label_pre cost_labels end_flag status_init status_end →
126          ¬ (is_call_p (current_instruction status_pre)) →
127          ¬ (is_jump_p (current_instruction status_pre)) →
128          (current_instruction status_pre) ≠ (RealInstruction … (RET [[relative]])) →
129          ¬ (current_instruction_is_labelled cost_labels status_init) →
130            trace_label_label_pre cost_labels end_flag status_pre status_end.
131*)
132
133(* XXX: not us
134definition compute_simple_path0 (s:Status) (is_labelled s) (well_balanced s) (labelled_p p): trace_lab_ret ≝ ….
135
136lemma simple_path_ok:
137 ∀st: Status.∀H.
138 let p ≝ compute_simple_path0 st H in
139   ∀n.
140    nth_path n p = execute n st ∧
141     (execute' (path_length p) st = 〈st',τ〉 →
142      τ = cost_trace p)
143  ].
144*)
145
146let rec compute_max_trace_label_label_cost
147  (cost_labels: BitVectorTrie costlabel 16)
148   (trace_ends_flag: trace_ends_with_ret)
149    (start_status: Status) (final_status: Status)
150      (the_trace: trace_label_label (ASM_abstract_status cost_labels) trace_ends_flag
151        start_status final_status) on the_trace: nat ≝
152  match the_trace with
153  [ tll_base ends_flag initial final given_trace labelled_proof ⇒
154      compute_max_trace_any_label_cost … given_trace
155  ]
156and compute_max_trace_any_label_cost
157  (cost_labels: BitVectorTrie costlabel 16)
158  (trace_ends_flag: trace_ends_with_ret)
159   (start_status: Status) (final_status: Status)
160     (the_trace: trace_any_label (ASM_abstract_status cost_labels) trace_ends_flag start_status final_status)
161       on the_trace: nat ≝
162  match the_trace with
163  [ tal_base_not_return the_status _ _ _ _ ⇒ current_instruction_cost the_status
164  | tal_base_return the_status _ _ _ ⇒ current_instruction_cost the_status
165  | tal_step_call end_flag pre_fun_call start_fun_call after_fun_call final
166     _ _ _ call_trace final_trace ⇒
167      let current_instruction_cost ≝ current_instruction_cost pre_fun_call in
168      let call_trace_cost ≝ compute_max_trace_label_return_cost … call_trace in
169      let final_trace_cost ≝ compute_max_trace_any_label_cost cost_labels end_flag … final_trace in
170        call_trace_cost + current_instruction_cost + final_trace_cost
171  | tal_step_default end_flag status_pre status_init status_end _ tail_trace _ _ ⇒
172      let current_instruction_cost ≝ current_instruction_cost status_pre in
173      let tail_trace_cost ≝
174       compute_max_trace_any_label_cost cost_labels end_flag
175        status_init status_end tail_trace
176      in
177        current_instruction_cost + tail_trace_cost
178  ]
179and compute_max_trace_label_return_cost
180  (cost_labels: BitVectorTrie costlabel 16)
181  (start_status: Status) (final_status: Status)
182    (the_trace: trace_label_return (ASM_abstract_status cost_labels) start_status final_status)
183      on the_trace: nat ≝
184  match the_trace with
185  [ tlr_base before after trace_to_lift ⇒ compute_max_trace_label_label_cost … trace_to_lift
186  | tlr_step initial labelled final labelled_trace ret_trace ⇒
187      let labelled_cost ≝ compute_max_trace_label_label_cost … labelled_trace in
188      let return_cost ≝ compute_max_trace_label_return_cost … ret_trace in
189        labelled_cost + return_cost
190  ].
191
192(*Useless now?
193(* To be moved *)
194lemma pred_minus_1:
195  ∀m, n: nat.
196  ∀proof: n < m.
197    pred (m - n) = m - n - 1.
198  #m #n
199  cases m
200  [ #proof
201    cases(lt_to_not_zero … proof)
202  | #m' #proof
203    normalize in ⊢ (???%);
204    cases n
205    [ normalize //
206    | #n' normalize
207      cases(m' - n')
208      [ %
209      | #Sm_n'
210        normalize //
211      ]
212    ]
213  ]
214qed.
215
216lemma succ_m_plus_one:
217  ∀m: nat.
218    S m = m + 1.
219 //
220qed.*)
221
222include alias "arithmetics/nat.ma".
223
224(*
225lemma minus_m_n_minus_minus_plus_1:
226  ∀m, n: nat.
227  ∀proof: n < m.
228    m - n = (m - n - 1) + 1.
229 /3 by lt_plus_to_minus_r, plus_minus/
230qed.
231*)
232
233lemma plus_minus_rearrangement_1:
234  ∀m, n, o: nat.
235  ∀proof_n_m: n ≤ m.
236  ∀proof_m_o: m ≤ o.
237    (m - n) + (o - m) = o - n.
238  #m #n #o #H1 #H2
239  lapply (minus_to_plus … H1 (refl …)) #K1 >K1
240  lapply (minus_to_plus … H2 (refl …)) #K2 >K2
241  /2 by plus_minus/
242qed.
243
244lemma plus_minus_rearrangement_2:
245  ∀m, n, o: nat. n ≤ m → o ≤ n →
246    (m - n) + (n - o) = m - o.
247 /2 by plus_minus_rearrangement_1/
248qed.
249
250axiom current_instruction_cost_non_zero:
251  ∀s: Status.
252    current_instruction_cost s > 0.
253   
254axiom minus_m_n_gt_o_0_le_n_m:
255  ∀m, n, o.
256  m - n = o → o > 0 → n ≤ m.
257
258let rec compute_max_trace_label_label_cost_is_ok
259  (cost_labels: BitVectorTrie costlabel 16)
260   (trace_ends_flag: trace_ends_with_ret)
261    (start_status: Status) (final_status: Status)
262      (the_trace: trace_label_label (ASM_abstract_status cost_labels) trace_ends_flag
263        start_status final_status) on the_trace:
264          And (compute_max_trace_label_label_cost cost_labels trace_ends_flag start_status final_status the_trace =
265            (clock … final_status) - (clock … start_status)) (clock … start_status ≤ clock … final_status) ≝ ?
266and compute_max_trace_any_label_cost_is_ok
267  (cost_labels: BitVectorTrie costlabel 16)
268  (trace_ends_flag: trace_ends_with_ret)
269   (start_status: Status) (final_status: Status)
270     (the_trace: trace_any_label (ASM_abstract_status cost_labels) trace_ends_flag start_status final_status)
271       on the_trace:
272         (compute_max_trace_any_label_cost cost_labels trace_ends_flag start_status final_status the_trace =
273           (clock … final_status) - (clock … start_status)) ∧ (clock … start_status ≤ clock … final_status) ≝ ?
274and compute_max_trace_label_return_cost_is_ok
275  (cost_labels: BitVectorTrie costlabel 16)
276  (start_status: Status) (final_status: Status)
277    (the_trace: trace_label_return (ASM_abstract_status cost_labels) start_status final_status)
278      on the_trace:
279        (compute_max_trace_label_return_cost cost_labels start_status final_status the_trace =
280          (clock … final_status) - (clock … start_status)) ∧ (clock … start_status ≤ clock … final_status) ≝ ?.
281  [1:
282    cases the_trace
283    #ends_flag #start_status #end_status #any_label_trace #is_costed
284    normalize @compute_max_trace_any_label_cost_is_ok
285  |2:
286    cases the_trace
287    [1:
288      #start_status #final_status #is_next #is_not_return #is_costed
289      change with (current_instruction_cost start_status) in ⊢ (?(??%?)?);
290      cases(is_next)
291      @conj
292      [1:
293        cases(execute_1 start_status)
294        #the_status #assm
295        whd in match eject; normalize nodelta
296        >assm %
297      |2:
298        cases(execute_1 start_status)
299        #the_status #assm
300        whd in match eject; normalize nodelta
301        @(minus_m_n_gt_o_0_le_n_m ? ? (current_instruction_cost start_status))
302        [1: assumption
303        |2: @current_instruction_cost_non_zero
304        ]
305      ]
306    |2:
307      #start_status #final_status #is_next #is_return
308      change with (current_instruction_cost start_status) in ⊢ (?(??%?)?);
309      cases(is_next)
310      @conj
311      [1:
312        cases(execute_1 start_status)
313        #the_status #assm
314        whd in match eject; normalize nodelta
315        >assm %
316      |2:
317        cases(execute_1 start_status)
318        #the_status #assm
319        whd in match eject; normalize nodelta
320        @(minus_m_n_gt_o_0_le_n_m ? ? (current_instruction_cost start_status))
321        [1: assumption
322        |2: @current_instruction_cost_non_zero
323        ]
324      ]
325    |3:
326      #end_flag #status_pre_fun_call #status_start_fun_call #status_after_fun_call
327      #status_final #is_next #is_call #is_after_return #call_trace #final_trace
328      change with (
329      let current_instruction_cost ≝ current_instruction_cost status_pre_fun_call in
330      let call_trace_cost ≝ compute_max_trace_label_return_cost … call_trace in
331      let final_trace_cost ≝ compute_max_trace_any_label_cost cost_labels end_flag … final_trace in
332        call_trace_cost + current_instruction_cost + final_trace_cost) in ⊢ (?(??%?)?);
333      normalize nodelta;
334      @conj
335      [1:
336        cases(compute_max_trace_label_return_cost_is_ok cost_labels status_start_fun_call
337          status_after_fun_call call_trace)
338        #trace_label_return_eq #trace_label_return_le
339        cases(compute_max_trace_any_label_cost_is_ok cost_labels end_flag status_after_fun_call
340          status_final final_trace)
341        #trace_any_label_eq #trace_any_label_le
342        >trace_label_return_eq >trace_any_label_eq
343        cases daemon (* XXX: complete me *)
344      |2:
345        cases daemon (* XXX: complete me *)
346      ]
347    |4:
348      #end_flag #status_pre #status_init #status_end #is_next
349      #trace_any_label #is_other #is_not_costed
350      cases daemon (* XXX: complete me *)
351    ]
352  |3:
353    cases the_trace
354    [1:
355      #status_before #status_after #trace_to_lift
356      normalize @compute_max_trace_label_label_cost_is_ok
357    |2:
358      #status_initial #status_labelled #status_final #labelled_trace #ret_trace
359      normalize
360      cases(compute_max_trace_label_label_cost_is_ok cost_labels doesnt_end_with_ret status_initial status_labelled labelled_trace);
361      #label_label_trace_equality #label_label_trace_leq
362      cases(compute_max_trace_label_return_cost_is_ok cost_labels status_labelled status_final ret_trace);
363      #label_return_trace_equality #label_return_trace_leq
364      >label_label_trace_equality >label_return_trace_equality
365      @conj
366      [2: @(transitive_le (clock (BitVectorTrie (Vector bool 8) 16) status_initial)
367            (clock (BitVectorTrie Byte 16) status_labelled)
368            (clock (BitVectorTrie (Vector bool 8) 16) status_final))
369      |1: @plus_minus_rearrangement_1
370      ]
371      assumption
372    ]
373  ]
374qed.
375
376(* XXX: work below here: *)
377
378let rec compute_paid_trace_any_label
379  (cost_labels: BitVectorTrie costlabel 16)
380  (trace_ends_flag: trace_ends_with_ret)
381   (start_status: Status) (final_status: Status)
382     (the_trace: trace_any_label (ASM_abstract_status cost_labels) trace_ends_flag start_status final_status)
383       on the_trace: nat ≝
384  match the_trace with
385  [ tal_base_not_return the_status _ _ _ _ ⇒ current_instruction_cost the_status
386  | tal_base_return the_status _ _ _ ⇒ current_instruction_cost the_status
387  | tal_step_call end_flag pre_fun_call start_fun_call after_fun_call final
388     _ _ _ call_trace final_trace ⇒
389      let current_instruction_cost ≝ current_instruction_cost pre_fun_call in
390      let final_trace_cost ≝ compute_paid_trace_any_label cost_labels end_flag … final_trace in
391        current_instruction_cost + final_trace_cost
392  | tal_step_default end_flag status_pre status_init status_end _ tail_trace _ _ ⇒
393      let current_instruction_cost ≝ current_instruction_cost status_pre in
394      let tail_trace_cost ≝
395       compute_paid_trace_any_label cost_labels end_flag
396        status_init status_end tail_trace
397      in
398        current_instruction_cost + tail_trace_cost
399  ].
400
401definition compute_paid_trace_label_label ≝
402 λcost_labels: BitVectorTrie costlabel 16.
403  λtrace_ends_flag: trace_ends_with_ret.
404   λstart_status: Status.
405    λfinal_status: Status.
406     λthe_trace: trace_label_label (ASM_abstract_status cost_labels) trace_ends_flag
407      start_status final_status.
408  match the_trace with
409  [ tll_base ends_flag initial final given_trace labelled_proof ⇒
410      compute_paid_trace_any_label … given_trace
411  ].
412
413let rec compute_trace_label_label_cost_using_paid
414  (cost_labels: BitVectorTrie costlabel 16)
415   (trace_ends_flag: trace_ends_with_ret)
416    (start_status: Status) (final_status: Status)
417      (the_trace: trace_label_label (ASM_abstract_status cost_labels) trace_ends_flag
418        start_status final_status) on the_trace: nat ≝
419  match the_trace with
420  [ tll_base ends_flag initial final given_trace labelled_proof ⇒
421      compute_paid_trace_label_label cost_labels … the_trace +
422      compute_trace_any_label_cost_using_paid … given_trace
423  ]
424and compute_trace_any_label_cost_using_paid
425  (cost_labels: BitVectorTrie costlabel 16)
426  (trace_ends_flag: trace_ends_with_ret)
427   (start_status: Status) (final_status: Status)
428     (the_trace: trace_any_label (ASM_abstract_status cost_labels) trace_ends_flag start_status final_status)
429       on the_trace: nat ≝
430  match the_trace with
431  [ tal_base_not_return the_status _ _ _ _ ⇒ 0
432  | tal_base_return the_status _ _ _ ⇒ 0
433  | tal_step_call end_flag pre_fun_call start_fun_call after_fun_call final
434     _ _ _ call_trace final_trace ⇒
435      let call_trace_cost ≝ compute_trace_label_return_cost_using_paid … call_trace in
436      let final_trace_cost ≝ compute_trace_any_label_cost_using_paid cost_labels end_flag … final_trace in
437        call_trace_cost + final_trace_cost
438  | tal_step_default end_flag status_pre status_init status_end _ tail_trace _ _ ⇒
439     compute_trace_any_label_cost_using_paid cost_labels end_flag
440      status_init status_end tail_trace
441  ]
442and compute_trace_label_return_cost_using_paid
443  (cost_labels: BitVectorTrie costlabel 16)
444  (start_status: Status) (final_status: Status)
445    (the_trace: trace_label_return (ASM_abstract_status cost_labels) start_status final_status)
446      on the_trace: nat ≝
447  match the_trace with
448  [ tlr_base before after trace_to_lift ⇒ compute_trace_label_label_cost_using_paid … trace_to_lift
449  | tlr_step initial labelled final labelled_trace ret_trace ⇒
450      let labelled_cost ≝ compute_trace_label_label_cost_using_paid … labelled_trace in
451      let return_cost ≝ compute_trace_label_return_cost_using_paid … ret_trace in
452        labelled_cost + return_cost
453  ].
454
455let rec compute_trace_label_label_cost_using_paid_ok
456  (cost_labels: BitVectorTrie costlabel 16)
457   (trace_ends_flag: trace_ends_with_ret)
458    (start_status: Status) (final_status: Status)
459      (the_trace: trace_label_label (ASM_abstract_status cost_labels) trace_ends_flag
460        start_status final_status) on the_trace:
461 compute_trace_label_label_cost_using_paid cost_labels … the_trace =
462 compute_max_trace_label_label_cost … the_trace ≝ ?
463and compute_trace_any_label_cost_using_paid_ok
464  (cost_labels: BitVectorTrie costlabel 16)
465  (trace_ends_flag: trace_ends_with_ret)
466   (start_status: Status) (final_status: Status)
467     (the_trace: trace_any_label (ASM_abstract_status cost_labels)
468      trace_ends_flag start_status final_status) on the_trace:     
469  compute_paid_trace_any_label cost_labels trace_ends_flag … the_trace
470  +compute_trace_any_label_cost_using_paid cost_labels trace_ends_flag … the_trace
471  =compute_max_trace_any_label_cost cost_labels trace_ends_flag … the_trace ≝ ?
472and compute_trace_label_return_cost_using_paid_ok
473  (cost_labels: BitVectorTrie costlabel 16)
474  (start_status: Status) (final_status: Status)
475    (the_trace: trace_label_return (ASM_abstract_status cost_labels)
476     start_status final_status) on the_trace:
477 compute_trace_label_return_cost_using_paid cost_labels … the_trace =
478 compute_max_trace_label_return_cost cost_labels … the_trace ≝ ?.
479[ cases the_trace #endsf #ss #es #tr #H normalize
480  @compute_trace_any_label_cost_using_paid_ok
481| cases the_trace
482  [ #ss #fs #H1 #H2 #H3 whd in ⊢ (??(?%%)%); <plus_n_O %
483  | #ss #fs #H1 #H2 whd in ⊢ (??(?%%)%); <plus_n_O %
484  | #ef #spfc #ssfc #safc #sf #H1 #H2 #H3 #tr1 #tr2 whd in ⊢ (??(?%%)%);
485    <compute_trace_any_label_cost_using_paid_ok
486    <compute_trace_label_return_cost_using_paid_ok
487    -compute_trace_label_label_cost_using_paid_ok
488    -compute_trace_label_return_cost_using_paid_ok
489    -compute_trace_any_label_cost_using_paid_ok
490    >commutative_plus in ⊢ (???(?%?));
491    >commutative_plus in ⊢ (??(??%)?);
492    >associative_plus >associative_plus in ⊢ (???%); @eq_f2 try %
493    <associative_plus <commutative_plus %
494  | #ef #sp #si #se #H1 #tr #H2 #H3 whd in ⊢ (??(?%%)%); >associative_plus @eq_f2
495    [ % | @compute_trace_any_label_cost_using_paid_ok ]
496  ]
497| cases the_trace
498  [ #sb #sa #tr normalize @compute_trace_label_label_cost_using_paid_ok
499  | #si #sl #sf #tr1 #tr2 normalize @eq_f2
500    [ @compute_trace_label_label_cost_using_paid_ok
501    | @compute_trace_label_return_cost_using_paid_ok ]]]
502qed.
503
504(*
505let rec compute_paid_trace_label_return
506  (cost_labels: BitVectorTrie costlabel 16)
507  (start_status: Status) (final_status: Status)
508    (the_trace: trace_label_return (ASM_abstract_status cost_labels) start_status final_status)
509      on the_trace: nat ≝
510 match the_trace with
511  [ tlr_base before after trace_to_lift ⇒ compute_paid_trace_label_label … trace_to_lift
512  | tlr_step initial labelled final labelled_trace ret_trace ⇒
513      let labelled_cost ≝ compute_paid_trace_label_label … labelled_trace in
514      let return_cost ≝ compute_paid_trace_label_return … ret_trace in
515        labelled_cost + return_cost
516  ].
517*)
518
519let rec compute_cost_trace_label_label
520  (cost_labels: BitVectorTrie costlabel 16)
521   (trace_ends_flag: trace_ends_with_ret)
522    (start_status: Status) (final_status: Status)
523      (the_trace: trace_label_label (ASM_abstract_status cost_labels) trace_ends_flag
524        start_status final_status) on the_trace:
525         list (Σk:costlabel. ∃pc. lookup_opt … pc cost_labels = Some … k) ≝
526  match the_trace with
527  [ tll_base ends_flag initial final given_trace labelled_proof ⇒
528     let pc ≝ program_counter … initial in
529     let label ≝
530      match lookup_opt … pc cost_labels return λx. match x with [None ⇒ False | Some _ ⇒ True] → costlabel with
531      [ None ⇒ λabs. ⊥
532      | Some l ⇒ λ_. l ] labelled_proof in
533     (dp … label ?)::compute_cost_trace_any_label … given_trace
534  ]
535and compute_cost_trace_any_label
536  (cost_labels: BitVectorTrie costlabel 16)
537  (trace_ends_flag: trace_ends_with_ret)
538   (start_status: Status) (final_status: Status)
539     (the_trace: trace_any_label (ASM_abstract_status cost_labels) trace_ends_flag start_status final_status)
540       on the_trace: list (Σk:costlabel. ∃pc. lookup_opt … pc cost_labels = Some … k) ≝
541  match the_trace with
542  [ tal_base_not_return the_status _ _ _ _ ⇒ []
543  | tal_base_return the_status _ _ _ ⇒ []
544  | tal_step_call end_flag pre_fun_call start_fun_call after_fun_call final
545     _ _ _ call_trace final_trace ⇒
546      let call_cost_trace ≝ compute_cost_trace_label_return … call_trace in
547      let final_cost_trace ≝ compute_cost_trace_any_label cost_labels end_flag … final_trace in
548        call_cost_trace @ final_cost_trace
549  | tal_step_default end_flag status_pre status_init status_end _ tail_trace _ _ ⇒
550       compute_cost_trace_any_label cost_labels end_flag
551        status_init status_end tail_trace
552  ]
553and compute_cost_trace_label_return
554  (cost_labels: BitVectorTrie costlabel 16)
555  (start_status: Status) (final_status: Status)
556    (the_trace: trace_label_return (ASM_abstract_status cost_labels) start_status final_status)
557      on the_trace: list (Σk:costlabel. ∃pc. lookup_opt … pc cost_labels = Some … k) ≝
558  match the_trace with
559  [ tlr_base before after trace_to_lift ⇒ compute_cost_trace_label_label … trace_to_lift
560  | tlr_step initial labelled final labelled_trace ret_trace ⇒
561      let labelled_cost ≝ compute_cost_trace_label_label … labelled_trace in
562      let return_cost ≝ compute_cost_trace_label_return … ret_trace in
563        labelled_cost @ return_cost
564  ].
565 [ %{pc} whd in match label;  generalize in match labelled_proof; whd in ⊢ (% → ?);
566  cases (lookup_opt costlabel … pc cost_labels) normalize
567  [ #abs cases abs | // ]
568 | // ]
569qed.
570
571(* ??????????????????????? *)
572axiom block_cost_static_dynamic_ok:
573 ∀cost_labels: BitVectorTrie costlabel 16.
574 ∀trace_ends_flag.
575 ∀start_status: Status.
576 ∀final_status: Status.
577 ∀the_trace:
578  trace_label_label (ASM_abstract_status cost_labels) trace_ends_flag
579   start_status final_status.
580 let mem ≝ code_memory … start_status in
581 let pc ≝ program_counter … start_status in
582 let program_size ≝ 2^16 in
583  block_cost mem cost_labels pc program_size =
584  compute_paid_trace_label_label cost_labels trace_ends_flag
585   start_status final_status the_trace.
586
587(*
588(* To be moved elsewhere*)
589lemma le_S_n_m_to_le_n_m: ∀n,m. S n ≤ m → n ≤ m.
590 #n #m #H change with (pred (S n) ≤ m) @(transitive_le ? (S n)) //
591qed.
592*)
593
594include "arithmetics/bigops.ma".
595
596(* This shoudl go in bigops! *)
597theorem bigop_sum_rev: ∀k1,k2,p,B,nil.∀op:Aop B nil.∀f:nat→B.
598 \big[op,nil]_{i<k1+k2|p i} (f i) =
599 op \big[op,nil]_{i<k2|p (i+k1)} (f (i+k1)) \big[op,nil]_{i<k1|p i} (f i).
600 #k1 #k2 #p #B #nil #op #f >bigop_sum >commutative_plus @same_bigop #i @leb_elim normalize
601 [2,4: //
602 | #H1 #H2 <plus_minus_m_m //
603 | #H1 #H2 #H3 <plus_minus_m_m //]
604qed.
605
606(* This is taken by sigma_pi.ma that does not compile now *)
607definition natAop ≝ mk_Aop nat 0 plus (λa.refl ? a) (λn.sym_eq ??? (plus_n_O n))
608   (λa,b,c.sym_eq ??? (associative_plus a b c)).
609
610definition natACop ≝ mk_ACop nat 0 natAop commutative_plus.
611
612definition natDop ≝ mk_Dop nat 0 natACop times (λn.(sym_eq ??? (times_n_O n)))
613   distributive_times_plus.
614
615unification hint  0 ≔ ;
616   S ≟ mk_Aop nat 0 plus (λa.refl ? a) (λn.sym_eq ??? (plus_n_O n))
617   (λa,b,c.sym_eq ??? (associative_plus a b c))
618(* ---------------------------------------- *) ⊢
619   plus ≡ op ? ? S.
620
621unification hint  0 ≔ ;
622   S ≟ mk_ACop nat 0 (mk_Aop nat 0 plus (λa.refl ? a) (λn.sym_eq ??? (plus_n_O n))
623   (λa,b,c.sym_eq ??? (associative_plus a b c))) commutative_plus
624(* ---------------------------------------- *) ⊢
625   plus ≡ op ? ? S.
626   
627unification hint  0 ≔ ;
628   S ≟ natDop
629(* ---------------------------------------- *) ⊢
630   plus ≡ sum ? ? S.
631
632unification hint  0 ≔ ;
633   S ≟ natDop
634(* ---------------------------------------- *) ⊢
635   times ≡ prod ? ? S.
636
637notation "Σ_{ ident i < n } f"
638  with precedence 20
639for @{'bigop $n plus 0 (λ${ident i}.true) (λ${ident i}. $f)}.
640
641axiom code_memory_ro_label_label:
642 ∀cost_labels. ∀ends_flag.
643 ∀initial,final. trace_label_label (ASM_abstract_status cost_labels) ends_flag initial final →
644  code_memory … initial = code_memory … final.
645
646(*
647axiom code_memory_ro_label_return:
648 ∀cost_labels.
649 ∀initial,final. trace_label_return (ASM_abstract_status cost_labels) initial final →
650  code_memory … initial = code_memory … final.
651*)
652
653definition tech_cost_of_label0:
654 ∀cost_labels: BitVectorTrie costlabel 16.
655 ∀cost_map: identifier_map CostTag nat.
656 ∀codom_dom: (∀pc,k. lookup_opt … pc cost_labels = Some … k → present … cost_map k).
657 ∀ctrace:list (Σk:costlabel.∃pc. lookup_opt costlabel 16 pc cost_labels = Some ? k).
658 ∀i,p. present … cost_map (nth_safe ? i ctrace p).
659 #cost_labels #cost_map #codom_dom #ctrace #i #p
660 cases (nth_safe … i ctrace ?) normalize #id * #id_pc #K
661 lapply (codom_dom … K) #k_pres >(lookup_lookup_present … k_pres)
662 % #abs destruct (abs)
663qed.
664
665lemma ltb_rect:
666 ∀P:Type[0].∀n,m. (n < m → P) → (¬ n < m → P) → P.
667 #P #n #m lapply (refl … (ltb n m)) cases (ltb n m) in ⊢ (???% → %); #E #H1 #H2
668 [ @H1 @leb_true_to_le @E | @H2 @leb_false_to_not_le @E ]
669qed.
670
671lemma same_ltb_rect:
672 ∀P,n,m,H1,H2,n',m',H1',H2'.
673  ltb n m = ltb n' m' → (∀x,y. H1 x = H1' y) → (∀x,y. H2 x = H2' y) →
674   ltb_rect P n m H1 H2 =
675   ltb_rect P n' m' H1' H2'.
676 #P #n #m #H1 #H2 #n' #m' #H1' #H2' #E #K1 #K2 whd in ⊢ (??%?);
677 cut (∀xxx,yyy,xxx',yyy'.
678   match ltb n m
679   return λx:bool.
680           eq bool (ltb n m) x
681            → (lt n m → P) → (Not (lt n m) → P) → P
682    with
683    [ true ⇒
684        λE0:eq bool (ltb n m) true.
685         λH10:lt n m → P.
686          λH20:Not (lt n m) → P. H10 (xxx E0)
687    | false ⇒
688        λE0:eq bool (ltb n m) false.
689         λH10:lt n m → P.
690          λH20:Not (lt n m) → P. H20 (yyy E0)]
691    (refl … (ltb n m)) H1 H2 =
692   match ltb n' m'
693   return λx:bool.
694           eq bool (ltb n' m') x
695            → (lt n' m' → P) → (Not (lt n' m') → P) → P
696    with
697    [ true ⇒
698        λE0:eq bool (ltb n' m') true.
699         λH10:lt n' m' → P.
700          λH20:Not (lt n' m') → P. H10 (xxx' E0)
701    | false ⇒
702        λE0:eq bool (ltb n' m') false.
703         λH10:lt n' m' → P.
704          λH20:Not (lt n' m') → P. H20 (yyy' E0)]
705    (refl … (ltb n' m')) H1' H2'
706  ) [2: #X @X]
707 >E cases (ltb n' m') #xxx #yyy #xxx' #yyy' normalize
708 [ @K1 | @K2 ]
709qed.
710
711
712definition tech_cost_of_label:
713 ∀cost_labels: BitVectorTrie costlabel 16.
714 ∀cost_map: identifier_map CostTag nat.
715 ∀codom_dom: (∀pc,k. lookup_opt … pc cost_labels = Some … k → present … cost_map k).
716 list (Σk:costlabel.∃pc. lookup_opt costlabel 16 pc cost_labels = Some ? k) →
717 nat → nat
718≝ λcost_labels,cost_map,codom_dom,ctrace,i.
719 ltb_rect ? i (|ctrace|)
720 (λH. lookup_present ?? cost_map (nth_safe ? i ctrace H) ?)
721 (λ_.0).
722 @tech_cost_of_label0 @codom_dom
723qed.
724
725lemma shift_nth_safe:
726 ∀T,i,l2,l1,K1,K2.
727  nth_safe T i l1 K1 = nth_safe T (i+|l2|) (l2@l1) K2.
728 #T #i #l2 elim l2 normalize
729  [ #l1 #K1 <plus_n_O #K2 %
730  | #hd #tl #IH #l1 #K1 <plus_n_Sm #K2 change with (? < ?) in K1; change with (? < ?) in K2;
731    whd in ⊢ (???%); @IH ]
732qed.
733
734lemma tech_cost_of_label_shift:
735 ∀cost_labels,cost_map,codom_dom,l1,l2,i.
736  i < |l1| →
737   tech_cost_of_label cost_labels cost_map codom_dom l2 i =
738   tech_cost_of_label cost_labels cost_map codom_dom (l1@l2) (i+|l1|).
739 #cost_labels #cost_Map #codom_dom #l1 #l2 #i #H
740 cut (ltb i (|l2|) = ltb (i+|l1|) (|l1@l2|))
741 [ change with (leb ?? = leb ??); @leb_elim
742   [ #H1 change with (i < ?) in H1; >le_to_leb_true [//] change with (? < ?)
743     >append_length >commutative_plus @monotonic_lt_plus_r //
744   | #H1 change with (¬ i < ?) in H1; >not_le_to_leb_false [//]
745     >append_length >commutative_plus % #H2
746     change with (? < ?) in H2; @(absurd ?? H1) @(lt_plus_to_lt_r … H2) ]
747 | #E whd in match tech_cost_of_label; normalize nodelta
748 @same_ltb_rect [@E]
749 [ #K1 #K2 lapply (shift_nth_safe ? i l1 l2 K1 K2) #H check eq_f
750   lapply (eq_f ?? (lookup_present CostTag nat cost_Map) ?? H)
751
752   
753 
754  cut (decide_bool (ltb i (|l2|)) = decide_bool (ltb (i+(|l1|)) (|l1@l2|)))
755  whd in match tech_cost_of_label; normalize nodelta
756   
757
758let rec compute_max_trace_label_return_cost_ok_with_trace
759 (cost_labels: BitVectorTrie costlabel 16)
760 (cost_map: identifier_map CostTag nat)
761 (initial: Status) (final: Status)
762 (trace: trace_label_return (ASM_abstract_status cost_labels) initial final)
763 (codom_dom: (∀pc,k. lookup_opt … pc cost_labels = Some … k → present … cost_map k))
764 (dom_codom:(∀k. ∀k_pres:present … cost_map k. ∃pc. lookup_opt … pc cost_labels = Some … k →
765   block_cost (code_memory … initial) cost_labels pc 2^16 = lookup_present … k_pres))
766 on trace:
767  let ctrace ≝ compute_cost_trace_label_return … trace in
768  compute_max_trace_label_return_cost … trace =
769   Σ_{i < |ctrace|} (tech_cost_of_label cost_labels cost_map codom_dom ctrace i)
770    ≝ ?.
771lapply (refl … initial) cases trace in ⊢ (??%? → %);
772[ #sb #sa #tr #_ whd in ⊢ (let ctrace ≝ % in ??%?);
773| #si #sl #sf #tr1 #tr2 #E whd in ⊢ (let ctrace ≝ % in ??%?);
774  change with (let ctrace ≝ ? in ? = bigop (|? @ ?|) ?????)
775  >append_length in ⊢ (let ctrace ≝ ? in ???(?%?????));
776  change with (?=?) >bigop_sum_rev >commutative_plus @eq_f2
777  [ >compute_max_trace_label_return_cost_ok_with_trace
778    -compute_max_trace_label_return_cost_ok_with_trace     
779    [3: @cost_map
780    |2: @codom_dom
781    |4:lapply (code_memory_ro_label_label … tr1) >E #E2 <E2 @dom_codom]
782    @same_bigop [//] #i #H #_ -dom_codom
783    generalize in match (compute_cost_trace_label_return cost_labels sl sf tr2); #l1
784    generalize in match (compute_cost_trace_label_label cost_labels doesnt_end_with_ret si sl tr1);
785
786i < |l1| →
787tech_cost_of_label cost_labels cost_map codom_dom l1 i =
788tech_cost_of_label cost_labels cost_map codom_dom (l2@l1) (i+|l1|)
789
790
791     whd in ⊢ (??%%);
792  |
793  ]
794]
795
796lemma
797 compute_max_trace_any_label_cost cost_label trace_ends_flag start_status
798  final_status the_trace =
799 
800
801let rec compute_paid_trace_label_label_cost
802  (cost_labels: BitVectorTrie Byte 16)
803   (trace_ends_flag: trace_ends_with_ret)
804    (start_status: Status) (final_status: Status)
805      (the_trace: trace_label_label (ASM_abstract_status cost_labels) trace_ends_flag
806        start_status final_status) on the_trace: nat ≝
807  match the_trace with
808  [ tll_base _ _ _ given_trace _ ⇒
809      compute_paid_trace_any_label_cost … given_trace
810  ]
811and compute_paid_trace_any_label_cost
812  (cost_labels: BitVectorTrie Byte 16)
813  (trace_ends_flag: trace_ends_with_ret)
814   (start_status: Status) (final_status: Status)
815     (the_trace: trace_any_label (ASM_abstract_status cost_labels) trace_ends_flag start_status final_status)
816       on the_trace: nat ≝
817  match the_trace with
818  [ tal_base_not_return the_status _ _ _ _ ⇒ current_instruction_cost the_status
819  | tal_base_return the_status _ _ _ ⇒ current_instruction_cost the_status
820  | tal_step_call end_flag pre_fun_call start_fun_call after_fun_call final
821     _ _ _ call_trace final_trace ⇒
822      let current_instruction_cost ≝ current_instruction_cost pre_fun_call in
823      let final_trace_cost ≝ compute_paid_trace_any_label_cost cost_labels end_flag … final_trace in
824        current_instruction_cost + final_trace_cost
825  | tal_step_default end_flag status_pre status_init status_end _ tail_trace _ _ ⇒
826      let current_instruction_cost ≝ current_instruction_cost status_pre in
827      let tail_trace_cost ≝
828       compute_paid_trace_any_label_cost cost_labels end_flag
829        status_init status_end tail_trace
830      in
831        current_instruction_cost + tail_trace_cost
832  ]
833and compute_paid_trace_label_return_cost
834  (cost_labels: BitVectorTrie Byte 16)
835  (start_status: Status) (final_status: Status)
836    (the_trace: trace_label_return (ASM_abstract_status cost_labels) start_status final_status)
837      on the_trace: nat ≝
838  match the_trace with
839  [ tlr_base before after trace_to_lift ⇒ compute_paid_trace_label_label_cost … trace_to_lift
840  | tlr_step initial labelled final labelled_trace ret_trace ⇒
841      let labelled_cost ≝ compute_paid_trace_label_label_cost … labelled_trace in
842      let return_cost ≝ compute_paid_trace_label_return_cost … ret_trace in
843        labelled_cost + return_cost
844  ].
845
846let rec trace_lab_rec_cost' (p: trace_lab_ret) : nat.
847 | (call b bf tr af tl) as self ⇒
848    trace_lab_lab_cost_nocall self + trace_lab_ret_cost' tr +
849    trace_lab_rec_cost' tl
850
851theorem main_lemma:
852 ∀p. trace_lab_rec_cost p = trace_lab_rec_cost' p.
853
854axiom lemma1:
855 ∀p: simple_path.
856  traverse_cost_internal (pc (hd p)) … = trace_lab_lab_cost_nocall p.
857
858axiom lemma2:
859 ∀s,l,cost_map.
860  is_labelled l s →
861   traverse_cost_internal s = cost_map l.
862
863axiom main_statement:
864 ∀s.
865 ∀cost_map.
866 let p ≝ compute_simple_path0 s in
867 ∑ (cost_trace p) cost_map = trace_lab_rec_cost' p.
868
869axiom main_statement:
870 ∀s.
871 ∀cost_map.
872 let p ≝ compute_simple_path0 s in
873  execute' (path_length p) s = 〈s',τ〉 →
874   Timer s' - Timer s = ∑ τ cost_map.
Note: See TracBrowser for help on using the repository browser.