(**************************************************************************) (* ___ *) (* ||M|| *) (* ||A|| A project by Andrea Asperti *) (* ||T|| *) (* ||I|| Developers: *) (* ||T|| The HELM team. *) (* ||A|| http://helm.cs.unibo.it *) (* \ / *) (* \ / This file is distributed under the terms of the *) (* v GNU General Public License Version 2 *) (* *) (**************************************************************************) include "Simulation.ma". include "Vm.ma". include "Lang_meas.ma". theorem cerco: ∀l_p : label_params. (* Given the operational semantics of a source program *) ∀S1: abstract_status l_p. (* Given the compiled assembly program *) ∀p,p',prog. (* Let S2 be the operational semantics of the compiled code *) let S2 ≝ asm_operational_semantics p l_p p' prog in (* If the simulation conditions between the source and compiled code holds (i.e. if the compiler is correct) *) ∀rel: relations … S1 S2. simulation_conditions … rel → (* Given an abstract interpretation framework for the compiled code *) ∀R: asm_abstract_interpretation p p' … prog. (* If the static analysis does not fail *) ∀mT,map1. ∀EQmap : static_analisys … (instr_map … R) mT prog = return map1. (* For every source trace whose measurable fragment starts in s1 and ends in s2 or, equivalently, whose state after the initial labelled transition is s1 and whose state after the final labelled transition is s2 *) ∀si,s1,s2,sn. ∀t: raw_trace … S1 … si sn. measurable … s1 s2 … t → (* For each target non I/O state si' in relation with the source state si *) ∀si': S2. as_classify … si' ≠ cl_io → Srel … rel si si' → (* There exists a corresponding target trace starting from si' *) ∃sn'. ∃t': raw_trace … si' sn'. Srel … rel sn sn' ∧ ∃EQ:get_costlabels_of_trace … t = get_costlabels_of_trace … t'. (* that has a measurable fragment starting in s1' and ending in s2' *) ∃s1',s2'. measurable … s1' s2' … t' ∧ (* Let labels be the costlabels observed in the trace (last one excluded) *) let labels ≝ chop … (get_costlabels_of_trace … t) in (* Let abs_actions be the list of statically computed abstract actions associated to each label in labels. *) ∀abs_actions. abs_actions = dependent_map … labels (λlbl,prf.(opt_safe … (get_map … map1 lbl) …)) → (* Given an abstract state in relation with the first state of the measurable fragment *) ∀a1.R s1' a1 → (* The final state of the measurable fragment is in relation with the one obtained by applying every semantics in abs_trace. *) R s2' (〚abs_actions〛 a1). [2: @hide_prf normalize nodelta in prf; >EQ in prf; #prf cases(mem_map ????? (labels_of_trace_are_in_code … (chop_mem … prf))) * #lbl' #pc * #Hmem #EQ destruct >(proj1 … (static_analisys_ok … EQmap … Hmem)) @(proj2 … (static_analisys_ok … EQmap … Hmem))] #l_p #S1 #p #p' #prog letin S2 ≝ (asm_operational_semantics ????) #rel #sim_conds #R #mT #map #EQmap #si #s1 #s2 #sn #t #Hmeas #si' #Hclass #Rsisi' cases (simulates_measurable … S1 S2 rel sim_conds … Hmeas … Rsisi') [2: #H cases Hclass >H #ABS cases(ABS (refl …)) ] #sn' * #t' ** #Rsnsn' #EQcostlabs * #s1' * #s2' #Hmeas' %{sn'} %{t'} %{Rsnsn'} %{EQcostlabs} %{s1'} %{s2'} %{Hmeas'} #acts #EQacts @(static_dynamic … EQmap … Hmeas') >rewrite_in_dependent_map [2: (\b (refl …)) normalize #EQ destruct] #x #xs #IH #l #a #H cases(is_permutation_case … H) #l1 * #l2 * #H1 #H2 destruct change with ([?]@?) in match (?::?); >big_op_associative >act_op >(IH … H1) big_op_associative in ⊢ (???%); >big_op_associative in ⊢ (???%); >(Hab … l1) >is_associative >act_op in ⊢ (???%); (proj1 … (static_analisys_ok … EQmap … Hmem)) @(proj2 … (static_analisys_ok … EQmap … Hmem)) ] #p #p' #prog #no_dup @pair_elim * #t_prog #m #keep #EQt_prog normalize nodelta #p_asm #p_asm' #prog_asm #rel #sim_cond #R #abelian #mT #map #EQmap #si #s1 #s2 #sn #t #meas_t #si' #Hclass * #si'' * #abs_top * #abs_tail * #Rsi_si'' #Rsi_si' lapply(correctness_theorem … p' prog no_dup) >EQt_prog normalize nodelta #H cases(H … meas_t … Rsi_si'') -H #abs_top' * #abs_tail' * #sn'' * #t'' ** #Rsn_sn'' #Hperm * #s1'' * #s2'' #meas_t'' cases(cerco … sim_cond … EQmap … meas_t'' … Rsi_si') // #sn' * #t' * #Rsn_sn' * #EQcost * #s1' * #s2' * #meas_t' normalize nodelta #Hcerco %{sn'} %{t'} % [ %{sn''} %{abs_top'} %{abs_tail'} /2 by conj/ ] % [ @(is_permutation_transitive … Hperm) >EQcost // ] %{s1'} %{s2'} %{meas_t'} #abs_actions #EQactions #a1 #Rs1_a1 >(action_on_permutation … abelian) [@Hcerco [% | assumption] | >EQactions -EQactions @is_permutation_dependent_map // | ] qed. (* TODO: 1. Spostare chop e eliminare suffix. 2. La block cost non fallisce in caso di I/O. 3. Integrare la prima passata di Language nel risultato finale 5. Cambi al control flow: Paolo's trick (label = coppia label-pezzo di stato) 6. Rappresentabilita' di I, [[ ]] e stati astratti =⇒ instrumentazione *) (* TO SAY 1) in una misurabile le silenti prima/dopo l'IO sono già automaticamente vuote (perchè una silente inizia/termina in un IO solo se vuota 2) non chiediamo di non potere transire in una iniziale/da un finale perchè non ci serve; se uno lo aggiunge ha automaticamente che le silenti sono vuote come nel caso IO. *)